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

时间:2008-08-28 02:00:01

标签: c# generics

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

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

但这感觉就像一块垃圾。有没有更好的方法来处理字符串案例?

6 个答案:

答案 0 :(得分:147)

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

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

答案 1 :(得分:14)

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

未经测试,但首先想到的是。

答案 2 :(得分:4)

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

答案 3 :(得分: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();
  }
}

答案 4 :(得分:0)

我知道这个问题很旧,但是已经有了更新。

从C#7.0开始,您可以使用#include "stdafx.h" using namespace System; value struct Field { String^ name; int fences; int length; Field(String^ x, int in_fences) { name = x; fences = in_fences; } void Init() { length = fences * 22; } }; int main(array<System::String ^> ^args) { array<Field>^ farm = { Field("eenie", 10 ), Field("meenie", 20 ), Field("miny", 4 ) }; for each (Field% field in farm) { field.Init(); } return 0; } 运算符比较类型。您不再需要像接受的答案中那样使用is

typeof

https://docs.microsoft.com/en-US/dotnet/csharp/language-reference/keywords/is

答案 5 :(得分:-6)

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

我必须使用以下代码来使泛型工作 -

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

    }