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

测试泛型类型是否为字符串的最佳方法?(C#),c#,generics,C#,Generics,我有一个泛型类,它应该允许任何类型,原语或其他类型。唯一的问题是使用default(T)。当您对值类型或字符串调用default时,它会将其初始化为合理的值(例如空字符串)。在对象上调用default(T)时,它返回null。出于各种原因,我们需要确保,如果它不是基元类型,那么我们将拥有该类型的默认实例,notnull。以下是尝试1: T createDefault() { if(typeof(T).IsValueType) { return default(T)

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

T createDefault()
{
    if(typeof(T).IsValueType)
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}
T createDefault()
{
if(类型(T).IsValueType)
{
返回默认值(T);
}
其他的
{
返回Activator.CreateInstance();
}
}
问题-字符串不是值类型,但它没有无参数构造函数。因此,目前的解决方案是:

T createDefault()
{
    if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}
T createDefault()
{
if(typeof(T).IsValueType | | typeof(T).FullName==“System.String”)
{
返回默认值(T);
}
其他的
{
返回Activator.CreateInstance();
}
}
但这感觉像是一场混乱。有更好的方法处理字符串大小写吗?

if(typeof(T).IsValueType | | typeof(T)=typeof(string))
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance<T>();
}
{ 返回默认值(T); } 其他的 { 返回Activator.CreateInstance(); }
未测试,但首先想到的是。

请记住默认值(string)为null,而不是string.Empty。您可能需要代码中的特殊情况:

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

您可以使用枚举。对实现IConvertible接口的类调用GetTypeCode方法,以获取该类实例的类型代码。IConvertible由Boolean、SByte、Byte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Decimal、DateTime、Char和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>();
            } 
        } 

    }
private T createDefault()
{ 
{     
if(类型(T).IsValueType)
{         
返回默认值(T);
}
else if(typeof(T).Name==“String”)
{
return(T)Convert.ChangeType(String.Empty,typeof(T));
}
其他的
{
返回Activator.CreateInstance();
} 
} 
}

我个人喜欢方法重载:

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();
  }
}
公共静态类扩展{
公共静态字符串空白(此字符串为me){
返回字符串。空;
}
公共静态T Blank(此T me){
var tot=类型(T);
返回tot.IsValueType
?默认值(T)
:(T)Activator.CreateInstance(tot)
;
}
}
班级计划{
静态void Main(字符串[]参数){
对象o=null;
字符串s=null;
int i=6;
Console.WriteLine(o.Blank());/“System.Object”
Console.WriteLine(s.Blank());/“”
Console.WriteLine(i.Blank());/“0”
Console.ReadKey();
}
}

我知道这个问题很老了,但有一个更新

由于C#7.0,您可以使用
is
操作符来比较类型。您不再需要在接受的答案中使用
typeof

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

我以为我早些时候尝试过那个解决方案,但它不起作用,但我一定做了什么蠢事。感谢您指出default(string)返回null,我们还没有因此遇到错误,但这是真的。@Matt Hamilton:+1,但您应该按照CodeInChaos的建议将答案更新为return'(T)(object)string.Empty',因为方法返回类型是泛型的,不能只返回字符串。
is
关键字呢?这不是很有用吗?目前不可能将is运算符应用于泛型和赋值或直接实例化,不是吗?按名称测试
String
,尤其是不考虑名称空间是坏的。我也不喜欢你改变信仰的方式。这并不能回答你提出的问题。这种方法不适用于泛型类型。