2013-09-30 14 views
0

我玩了一下週圍有確定對象的默認值的基礎上,在這裏例如:System.Type的創建檢索'默認'值的通用擴展方法?

https://stackoverflow.com/a/3195792/1293496

這個特殊的擴展方法。我試圖完成是使這個更加通用的,在那裏我可以做這樣的事情:

int i = 3; 
bool amIaDefaultValue = i.IsDefaultValue(); 

我希望它可以返回true,如果我== 0(類型爲int的默認值),而對於其他所有情況則爲false。

這是我初步的嘗試:

public static bool IsDefaultValue<T>(this T value) 
{ 
    var t = typeof(T); // always comes back as object..? 

    if (t.IsValueType && Nullable.GetUnderlyingType(t) == null) 
    { 
     return value.Equals(Activator.CreateInstance<T>()); 
    } 
    else 
    { 
     var defaultValue = default(T); 

     if (value == null) 
      return defaultValue == null; 
     else 
      return value.Equals(defaultValue); 
    } 
} 

從有利的一面,我能夠.IsDefaultValue()連接到任何物體。不幸的是,T的類型總是以System.Object的形式返回。我能得到正確的類型,如果我將它設置了這種方式:

var t = typeof(value); 

但是,如果值正好是空的,我會得到一個錯誤,立竿見影。是否有一個很好的解決方法來實現這樣的擴展方法?或者我應該堅持這個例子中久經考驗的路線嗎?

編輯 正如指出的意見,看來我這個過於簡單化了一下,錯過了問題的根源。下面是實際打電話給我IsDefaultValue():

foreach (var imprintProperty in deltas.GetType().GetProperties()) 
{ 
    var value = imprintProperty.GetValue(deltas); 
    if (!value.IsDefaultValue()) 
    { 
     // get corresponding prop in programmable area 
     var programmableProp = progarea.GetType().GetProperty(imprintProperty.Name); 
     if (programmableProp != null) 
      programmableProp.SetValue(progarea, value); 
    } 
} 

而現在它變得很明顯,.GetValue總是返回作爲System.Object的。 UFF。

是否仍有可能將對象作爲擴展方法中的基礎類型?對不起,這個混亂。

+4

我沒有看到你的行爲描述,用'3.IsValueDefault()'調用你的方法並在你的擴展方法中添加一個'Console.WriteLine(t)'在控制檯上產生預期的'System.Int32'。在你的方法中'typeof(value)'也是一個編譯器錯誤。你沒有告訴我們什麼? –

+0

我也無法重現「總是獲取對象」作爲類型。 –

+2

當你調用這個方法時,你是否確信'_'的_design-time_類型被稱爲'int'?如在,你沒有這樣的東西:'對象我= 3; bool amIaDefaultValue = i.IsDefaultValue();'? (另外,無論如何,你可能想要使用'value.GetType()'(檢查空值!),就好像你傳入一個值類型作爲基礎對象一樣,或者將它作爲一個接口來傳遞會得到不正確的結果,因爲'default(T)'將返回'null') –

回答

0

看看這個:

static class Program 
{ 
    static void Main() 
    { 
     int a = 1; 

     Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue()); 

     a = 0; 

     Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue()); 

     object obj = new object(); 

     Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue()); 

     obj = null; 

     Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue()); 

     int? b = 1; 

     Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue()); 

     b = null; 

     Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue()); 

     Console.ReadKey(true); 
    } 

    static bool IsDefaultValue<T>(this T value) 
    { 
     if (ReferenceEquals(value, null)) 
     { 
      return true; 
     } 

     var t = value.GetType(); 

     if (t.IsValueType) 
     { 
      return value.Equals(Activator.CreateInstance(value.GetType())); 
     } 

     return false; 
    } 
} 

顯然作品(我說,我確信其他的方式應該有工作,但沒有)

+0

對於int?類型,IsDefaultValue()對於0和null返回true。它應該只返回null爲空。我對Nullable類型和泛型不能很好地發揮作用有這樣的印象。 – MadHenchbot