简体   繁体   中英

How to initialize generic parameter type T?

Simple question:
If you have a string x , to initialize it you simple do one of the following:

string x = String.Empty;  

or

string x = null;

What about Generic parameter T?

I've tried doing:

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

Generate error:
Cannot create an instance of the variable type 'T' because it does not have the new() constraint

You have two options:

You can constrain T: you do this by adding: where T : new() to your method. Now you can only use the someMethod with a type that has a parameterless, default constructor (see Constraints on Type Parameters ).

Or you use default(T) . For a reference type, this will give null . But for example, for an integer value this will give 0 (see default Keyword in Generic Code ).

Here is a basic console application that demonstrates the difference:

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);
        }

    }
}

It produces the following output:

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

use default keyword.

T x = default(T);

See: default Keyword in Generic Code (C# Programming Guide)

Given a variable t of a parameterized type T, the statement t = null is only valid if T is a reference type and t = 0 will only work for numeric value types but not for structs. The solution is to use the default keyword, which will return null for reference types and zero for numeric value types. For structs, it will return each member of the struct initialized to zero or null depending on whether they are value or reference types.

You need to add a new constraint for the type parameter T .

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

This will only be valid for types with a default constructor however.

The where clause for T is a generic type constraint . In this case, it requires that any type T this method is applied to must have a public parameterless constructor.

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

Activator.CreateInstance()

You may use default construct to set it to whatever that Type's default is.

The default keyword allows you to tell the compiler that at compile time the default value of this variable should be used. If the type argument supplied is a numeric value (eg, int, long, decimal), then the default value is zero. If the type argument supplied is a reference type, then the default value is null. If the type argument supplied is a struct, then the default value of the struct is determined by initializing each member field of the struct to zero for numeric types or null for reference types.

Use something like :

T data = default(T);

For details, read : Initializing Generic Variables to Their Default Values

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM