2008-08-28 88 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(); 
    } 
} 
相关问题