104

我有一个泛型类,它应该允许任何类型,原始类型或其他类型。唯一的问题是使用default(T). 当您对值类型或字符串调用 default 时,它会将其初始化为合理的值(例如空字符串)。当你调用default(T)一个对象时,它返回 null。由于各种原因,我们需要确保如果它不是原始类型,那么我们将拥有该类型的默认实例,而不是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>();
    }
}

但这感觉就像一个杂牌。有没有更好的方法来处理字符串大小写?

4

6 回答 6

181

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

if (typeof(T) == typeof(String)) return (T)(object)String.Empty;
于 2008-08-28T02:08:18.670 回答
14
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance<T>();
}

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

于 2008-08-28T02:06:30.000 回答
4

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

于 2008-08-28T02:18:09.503 回答
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();
  }
}
于 2015-02-10T15:50:21.883 回答
-1

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

从 C# 7.0 开始,您可以使用is运算符来比较类型。您不再需要typeof在接受的答案中使用 as 。

        public bool IsObjectString(object obj)
        {
            return obj is string;
        }

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

于 2020-09-11T10:32:49.427 回答
-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>();
            } 
        } 

    }
于 2011-02-13T12:25:03.763 回答