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

Jav*_*aSa 22 .net c# generics

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

string x = String.Empty;  
Run Code Online (Sandbox Code Playgroud)

要么

string x = null;
Run Code Online (Sandbox Code Playgroud)

通用参数T怎么样?

我试过做:

void someMethod<T>(T y)
{
    T x = new T();  
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

Wou*_*ort 35

您有两种选择:

您可以约束T:您可以通过向where T : new()您的方法添加:来实现此目的.现在,您只能使用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);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

它产生以下输出:

New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False
Run Code Online (Sandbox Code Playgroud)


Hab*_*bib 10

使用default关键字.

T x = default(T);
Run Code Online (Sandbox Code Playgroud)

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

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


Lee*_*Lee 7

您需要new为type参数添加约束T.

void someMethod<T>(T y) where T : new()
{
    T x = new T();  
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

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


Osc*_*car 5

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

Activator.CreateInstance()
Run Code Online (Sandbox Code Playgroud)