C# 如何初始化泛型参数类型T?

C# 如何初始化泛型参数类型T?,c#,.net,generics,C#,.net,Generics,简单问题: 如果您有一个字符串x,要对其进行初始化,只需执行以下操作之一: string x = String.Empty; 或 那么泛型参数T呢 我试过做: void someMethod<T>(T y) { T x = new T(); ... } void somethod(T y) { T x=新的T(); ... } 生成错误: 无法创建变量类型“T”的实例,因为它没有new()约束使用默认值关键字 T x = default(T); 见:

简单问题:
如果您有一个
字符串x
,要对其进行初始化,只需执行以下操作之一:

string x = String.Empty;  

那么泛型参数T呢

我试过做:

void someMethod<T>(T y)
{
    T x = new T();  
    ...
}
void somethod(T y)
{
T x=新的T();
...
}
生成错误:

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

使用
默认值
关键字

T x = default(T);
见:

给定参数化类型t的变量t,语句t=null 仅当T是引用类型且T=0仅适用于 数值类型,但不适用于结构。解决方法是使用 默认关键字,它将为引用类型返回null,为零 对于数值类型。对于结构,它将返回 结构初始化为零或null,具体取决于它们是否为零 值或引用类型


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

void someMethod<T>(T y) where T : new()
{
    T x = new T();  
    ...
}
void someMethod(ty),其中T:new()
{
T x=新的T();
...
}
但是,这仅对具有默认构造函数的类型有效

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

您有两个选项:

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

或者使用
默认值(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);
        }

    }
}

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

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

使用类似于:

T数据=默认值(T)


有关详细信息,请阅读:

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

Activator.CreateInstance()

“因为它没有new()约束”=>添加
new()
约束。Simples:)@Lee default and parameterless:DCan您能解释一下在
where:
语法中发生了什么吗?@JavaSa@JavaSa-我已经添加了一个解释。为什么要在您不知道类型的位置执行此操作?另外,如果您有
where t:struct
那么
t=new t()并生成与
默认值(T)
相同的值。如果您有约束
其中U:class
,则
U=null并等效于
默认值(U)
。约束
其中U:new()
可以与
组合,但不能与
结构
组合。几年后。。。。如果您的类型是数值基元类型,则此操作非常有效。它们具有生成零默认值的默认构造函数。
New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False
Activator.CreateInstance()