28

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

string x = String.Empty;  

或者

string x = null;

泛型参数 T 呢?

我试过做:

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

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

4

5 回答 5

42

你有两个选择:

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

或者你使用default(T). 对于引用类型,这将给出null. 但是例如,对于一个整数值,这将给出0(参见通用代码中的默认关键字)。

这是一个演示差异的基本控制台应用程序:

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
于 2012-12-21T11:16:01.877 回答
13

使用default关键字。

T x = default(T);

请参阅:通用代码中的默认关键字(C# 编程指南)

给定参数化类型 T 的变量 t,语句 t = null 仅在 T 是引用类型且 t = 0 仅适用于数值类型而不适用于结构时才有效。解决方案是使用 default 关键字,它将为引用类型返回 null,而为数值类型返回零。对于结构,它将返回结构的每个成员,根据它们是值类型还是引用类型,初始化为零或空。

于 2012-12-21T11:14:43.670 回答
9

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

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

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

wherefor 子句是T一个泛型类型约束。在这种情况下,它要求T应用此方法的任何类型都必须具有公共无参数构造函数。

于 2012-12-21T11:14:56.417 回答
4

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

Activator.CreateInstance()
于 2012-12-21T11:30:47.737 回答
0

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

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

使用类似的东西:

T data = default(T);

有关详细信息,请阅读:将通用变量初始化为其默认值

于 2012-12-21T11:19:49.880 回答