如何初始化通用参数类型T?

时间:2012-12-21 11:14:12

标签: c# .net generics

简单问题:
如果您有string x,要初始化它,您只需执行以下操作之一:

string x = String.Empty;  

string x = null;

通用参数T怎么样?

我尝试过:

void someMethod<T>(T y)
{
    T x = new T();  
    ...
}

产生错误:
无法创建变量类型'T'的实例,因为它没有new()约束

5 个答案:

答案 0 :(得分:32)

您有两种选择:

您可以约束T:您可以通过向您的方法添加:where T : new()来执行此操作。现在,您只能将someMethod与具有无参数的默认构造函数的类型一起使用(请参阅Constraints on Type Parameters)。

或者您使用default(T)。对于参考类型,这将给出null。但是,例如,对于整数值,这将给出0(请参阅default Keyword in Generic Code)。

这是一个基本的控制台应用程序,它展示了不同之处:

using System;

namespace Stackoverflow
{
    class Program
    {
        public static T SomeNewMethod<T>()
            where T : new()
        {
            return new T();
        }

        public static T SomeDefaultMethod<T>()
            where T : new()
        {
            return default(T);
        }

        struct MyStruct { }

        class MyClass { }

        static void Main(string[] args)
        {
            RunWithNew();
            RunWithDefault();
        }

        private static void RunWithDefault()
        {
            MyStruct s = SomeDefaultMethod<MyStruct>();
            MyClass c = SomeDefaultMethod<MyClass>();
            int i = SomeDefaultMethod<int>();
            bool b = SomeDefaultMethod<bool>();

            Console.WriteLine("Default");
            Output(s, c, i, b);
        }

        private static void RunWithNew()
        {
            MyStruct s = SomeNewMethod<MyStruct>();
            MyClass c = SomeNewMethod<MyClass>();
            int i = SomeNewMethod<int>();
            bool b = SomeNewMethod<bool>();

            Console.WriteLine("New");
            Output(s, c, i, b);
        }

        private static void Output(MyStruct s, MyClass c, int i, bool b)
        {
            Console.WriteLine("s: " + s);
            Console.WriteLine("c: " + c);
            Console.WriteLine("i: " + i);
            Console.WriteLine("b: " + b);
        }

    }
}

它产生以下输出:

New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False

答案 1 :(得分:10)

使用default关键字。

T x = default(T);

请参阅:default Keyword in Generic Code (C# Programming Guide)

  

给定参数化类型T的变量t,语句t = null   仅当T是引用类型且t = 0才有效时才有效   数值类型,但不适用于结构。解决方案是使用   default关键字,它将为引用类型返回null并为零   对于数值类型。对于结构,它将返回每个成员   struct初始化为零或null,具体取决于它们是否为   价值或参考类型。

答案 2 :(得分:7)

您需要为类型参数new添加T约束。

void someMethod<T>(T y) where T : new()
{
    T x = new T();  
    ...
}

这仅对具有默认构造函数的类型有效。

where的{​​{1}}条款是generic type constraint。在这种情况下,它要求应用此方法的任何类型T必须具有公共无参数构造函数。

答案 3 :(得分:4)

如果您确实需要T的实例而不是引用类型的默认空值,请使用:

Activator.CreateInstance()

答案 4 :(得分:0)

您可以使用default构造将其设置为Type的默认值。

default关键字允许您告诉编译器在编译时应该使用此变量的默认值。如果提供的type参数是数值(例如,int,long,decimal),则默认值为零。如果提供的type参数是引用类型,则默认值为null。如果提供的类型参数是结构,则通过将结构的每个成员字段初始化为数字类型的零或引用类型为null来确定结构的默认值。

使用类似:

T data = default(T);

有关详情,请阅读:Initializing Generic Variables to Their Default Values