2011-07-16 83 views
2

我有一个从孤立存储中提取对象的类。如果它找不到有问题的对象,它将返回默认值(T),因为它们是引用类型,所以它将为空。如果返回的值为空,我会做一个简单的检查并在调用者中分配一个新实例,但我更愿意在存储逻辑中执行此操作。在泛型中返回一个新实例而不是空实例

所以我的问题,有没有办法返回一个新的T的对象有一个默认的空白构造函数?

+0

可能的重复[通过Activator.CreateInstance创建可为空的对象返回null](http://stackoverflow.com/questions/8691601/creating-a-nullable-object-via-activator-createinstance-returns- null) – nawfal

回答

13

一种选择是使用该限制的“新”: http://msdn.microsoft.com/en-us/library/sd2w2ew5(v=vs.80).aspx

像这样:

public T GetNewItem() 
    where T: new() 
{ 
    return new T(); 
} 

但有这个限制意味着,没有你不能使用类型默认构造函数。所以,你可以考虑使用System.Activator.CreateInstance,但请记住,它可能会抛出异常:

T createInstance<T>() 
{ 
    try 
    { 
     return System.Activator.CreateInstance<T>(); 
    } 
    catch (MissingMethodException exc) 
    { 
     return default(T); 
    } 
} 

因此,它可能是知道好主意,如果给定类型支持的初始化这个月初,方法如下:

T createInstance<T>() 
{ 
    System.Reflection.ConstructorInfo constructor = (typeof(T)).GetConstructor(System.Type.EmptyTypes); 
    if (ReferenceEquals(constructor, null)) 
    { 
     //there is no default constructor 
     return default(T); 
    } 
    else 
    { 
     //there is a default constructor 
     //you can invoke it like so: 
     return (T)constructor.Invoke(new object[0]); 
     //return constructor.Invoke(new object[0]) as T; //If T is class 
    } 
} 

当你在这里,为什么不能创建一个实例的委托?

Func<T> getConstructor<T>() 
{ 
    System.Reflection.ConstructorInfo constructor = (typeof(T)).GetConstructor(System.Type.EmptyTypes); 
    if (ReferenceEquals(constructor, null)) 
    { 
     return() => { return default(T); }; 
    } 
    else 
    { 
     return() => { return (T)constructor.Invoke(new object[0]); }; 
    } 
} 

的如何使用它的示例(编译LinqPad):

void Main() 
{ 
    Console.WriteLine(getConstructor<object>()()); 
    Console.WriteLine(getConstructor<int>()()); 
    Console.WriteLine(getConstructor<string>()()); 
    Console.WriteLine(getConstructor<decimal>()()); 
    Console.WriteLine(getConstructor<DateTime>()()); 
    Console.WriteLine(getConstructor<int?>()()); 
} 

的输出是:

System.Object 
0 
null 
0 
01/01/0001 12:00:00 a.m. 
null 

字符串的情况下,是一种特殊的情况下,作为一个referece键入它可以为null,并且不具有公共默认构造函数,而不是String.Empty。可空类型也给出null。

+0

非常全面的欢呼声! – deanvmc

2

new()约束添加到您的泛型方法:

public T Create<T>() where T: class, new() 
{ 
    return new T(); 
} 
3

您可以将约束添加到您的类型参数,但将排除被不支持空参数的构造函数的类用作类型参数。

public class Foo<T> where T : new() 
{ 
    // Now you can say T blah = new T(); 
} 

您也可以拨打Activator.CreateInstance<T>(),但如果类型没有正确的构造函数将抛出。

我认为如果找不到对象,并且让调用代码处理它认为合适的条件,你可能会更好,因为记录下你的方法返回null。知道如何继续下去将是最好的选择。

1

此作品:

使用系统;

public class Test 
{ 
    static T CreateT<T>(bool _new) where T: new() 
    { 
     if (_new) return new T(); else return default(T); 
    } 
    public static void Main() 
    { 
     var o = CreateT<object>(true); 
    } 
} 
相关问题