测试泛型类型是否为字符串的最佳方法? (C#)

测试泛型类型是否为字符串的最佳方法? (C#)

Best way to test if a generic type is a string? (C#)

我有一个通用类,应允许任何类型,原始或其他类型。 唯一的问题是使用default(T)。 当您对值类型或字符串调用default时,它将初始化为一个合理的值(例如空字符串)。 在对象上调用default(T)时,它返回null。 由于各种原因,我们需要确保它不是原始类型,那么我们将拥有该类型的默认实例,而不是null。 这是尝试1:

1
2
3
4
5
6
7
8
9
10
11
T createDefault()
{
    if(typeof(T).IsValueType)
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance< T >();
    }
}

问题-字符串不是值类型,但是它没有无参数构造函数。 因此,当前的解决方案是:

1
2
3
4
5
6
7
8
9
10
11
T createDefault()
{
    if(typeof(T).IsValueType || typeof(T).FullName =="System.String")
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance< T >();
    }
}

但这感觉就像是在跳动。 有没有更好的方法来处理字符串大小写?


请记住,default(string)为null,而不是string.Empty。 您可能需要在代码中使用特殊情况:

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

1
2
3
4
5
6
7
8
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance< T >();
}

未经测试,但想到的第一件事。


您可以使用TypeCode枚举。 在实现IConvertible接口的类上调用GetTypeCode方法,以获取该类实例的类型代码。 IConvertible由Boolean,SByte,Byte,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double,Decimal,DateTime,Char和String实现,因此您可以使用此方法检查原始类型。 有关"通用类型检查"的更多信息。


就个人而言,我喜欢方法重载:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
  }
}

有关String的讨论在这里不起作用。

我必须有以下泛型代码才能使其正常工作-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   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 >();
            }
        }

    }


推荐阅读