2011-05-18 35 views
2

我有这样的事情如何创建一个可以初始化值变量为0或引用变量来新(NOT NULL)

V Func<V>() 
{ 
    // do stuff 
    V res = default(V); 
// more stuff 
    return res; 
} 

的问题是,我想水库是0或一个新的通用方法V

的实例

我尝试创建2种方法

Func<V> where T: new() 
Func<V> where T: struct 

但令人惊讶的,这是不允许

我的解决办法是有2个功能

FuncNew<V> where T: new() 
... 
res = new V(); 
.... 

FuncDefault<V> where T: struct 
... 
res = default(V) 
... 

编辑:总结答案

新(T)将新建立一个ref或值类型;我没有意识到

+1

什么是确定返回值是否是'V'或0的新实例? – Oded 2011-05-18 20:28:08

+0

你甚至没有写出正确的方法声明,而'where T:new'的约束是无效的。即使它*有效,您也不能通过类型约束来重载方法。 – 2011-05-18 20:28:20

+4

在您尝试的解决方案中,[约束不是签名的一部分](http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the- signature.aspx)。 – 2011-05-18 20:28:40

回答

6

可以使用new()约束:

private V Func<V>() where V : new() 
{ 
    // do stuff 
    V res = new V(); 
// more stuff 
    return res; 
} 

值类型会被初始化为全零,任何引用类型将使用他们的无参数的默认构造函数初始化。

如果引用类型没有无参数的构造函数,它不能用于这个方法,你必须使用其他方法(SO上的其他地方有很多解决这个问题的方法,例如Passing arguments to C# generic new() of templated type

+1

注意,对于任何结构(包括'Nullable '),'new T()'等价于'default(T)'。 – 2011-05-18 20:27:44

+0

这不适用于值类型 – pm100 2011-05-18 20:48:37

+0

return V;有点鱼腥味:) – 2011-05-18 20:49:15

0

所以你想结果对象是整数零,或者你的泛型类型的新实例?这是不可能的,因为泛型类型参数只对整数类型有效,除非你指定object作为返回类型。

public object Func<T>() 
    where T: new() 
{ 
    if(something) 
     return 0; 

    return new T(); 
} 

如果您正在尝试制作默认初始化程序,则只需要新建该类型即可。这应该适用于整数类型和参考类型。

public T Func<T>() 
{ 
    return Activator.CreateInstance<T>(); 
} 
+0

一般来说,最好直接使用'new T()'而不是'Activator.CreateInstance ',因为C#编译器会插入一些优化以使其非常快速值类型。 – thecoop 2011-05-18 20:37:15

+0

确实。看过你的实现后,'new()'更简洁。 – Tejs 2011-05-18 20:38:45

+0

我需要测试的'东西'是V是ref还是值类型 – pm100 2011-05-18 20:49:23