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

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

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>();
}
}

但是这感觉像是一个组装件,有没有更好的方法来处理这个线盒?

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

Untested, but the first thing that came to mind.

Keep in mind that default(string) is null, not string.Empty. You may want a special case in your code:

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

You can use the TypeCode enumeration. Call the GetTypeCode method on classes that implement the IConvertible interface to obtain the type code for an instance of that class. IConvertible is implemented by Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String, so you can check for primitive types using this. More info on "Generic Type Checking".

The discussion for String is not working here.

I had to have following code for generics to make it work -

   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>();
}
}


}

Personally, I like method overloading:

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();
}
}