2008-08-28 95 views
78

我有一個泛型類應該允許任何類型,基元或其他。唯一的問題是使用default(T)。當您在值類型或字符串上調用默認值時,會將其初始化爲合理的值(如空字符串)。當您在對象上調用default(T)時,它將返回null。由於各種原因,我們需要確保如果它不是原始類型,那麼我們將有一個類型的默認實例,而不是 null。這裏是嘗試1:測試泛型類型是字符串的最佳方法是什麼? (C#)

T createDefault() 
{ 
    if(typeof(T).IsValueType) 
    { 
     return default(T); 
    } 
    else 
    { 
     return Activator.CreateInstance<T>(); 
    } 
} 

問題 - 字符串不是一個值類型,但它沒有無參數的構造函數。因此,目前的解決方案是:

T createDefault() 
{ 
    if(typeof(T).IsValueType || typeof(T).FullName == "System.String") 
    { 
     return default(T); 
    } 
    else 
    { 
     return Activator.CreateInstance<T>(); 
    } 
} 

但是,這感覺就像一個雜牌。有更好的方法來處理字符串的情況嗎?

回答

133

請記住,默認(字符串)爲空,而不是string.Empty。您可能需要在代碼中使用特例:

if (typeof(T) == typeof(String)) return (T)(object)String.Empty; 
+2

我以爲我試過早些時候,解決方案,它沒有工作,但我一定做了一些愚蠢的事情。感謝您指出默認(字符串)返回null,我們沒有因爲它而遇到錯誤,但這是真的。 – 2010-05-29 00:32:26

+1

@Matt Hamilton:+1,但你應該更新你的答案,返回CodeInChaos建議的'(T)(object)String.Empty',因爲方法返回類型是泛型的,你不能只返回字符串。 – VoodooChild 2012-01-23 17:04:09

13
if (typeof(T).IsValueType || typeof(T) == typeof(String)) 
{ 
    return default(T); 
} 
else 
{ 
    return Activator.CreateInstance<T>(); 
} 

未經測試,但首先想到的。

4

您可以使用TypeCode枚舉。對實現IConvertible接口的類調用GetTypeCode方法,以獲取該類實例的類型代碼。 IConvertible由布爾,SByte,Byte,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double,Decimal,DateTime,Char和String實現,因此您可以使用它檢查基本類型。有關更多信息「Generic Type Checking」。

-6

關於字符串的討論在這裏不起作用。

我必須有下面的代碼爲仿製藥,使其工作 -

private T createDefault() 
    { 

     {  
      if(typeof(T).IsValueType)  
      {   
       return default(T);  
      } 
      else if (typeof(T).Name == "String") 
      { 
       return (T)Convert.ChangeType(String.Empty,typeof(T)); 
      } 
      else 
      { 
       return Activator.CreateInstance<T>(); 
      } 
     } 

    } 
2

就個人而言,我喜歡重載方法:

public static class Extensions { 
    public static String Blank(this String me) {  
    return String.Empty; 
    } 
    public static T Blank<T>(this T me) {  
    var tot = typeof(T); 
    return tot.IsValueType 
     ? default(T) 
     : (T)Activator.CreateInstance(tot) 
     ; 
    } 
} 
class Program { 
    static void Main(string[] args) { 
    Object o = null; 
    String s = null; 
    int i = 6; 
    Console.WriteLine(o.Blank()); //"System.Object" 
    Console.WriteLine(s.Blank()); //"" 
    Console.WriteLine(i.Blank()); //"0" 
    Console.ReadKey(); 
    } 
} 
相關問題