Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When new-able use new T(), otherwise use default(T)

I am working on a C# generic function. When error, if the generic type can be new-able, return new T(), otherwise return default(T).

The code like this:

private T Func<T>()
{
    try
    {
        // try to do something...
    }
    catch (Exception exception)
    {
        if (T is new-able) // <---------- How to do this?
        {
            return new T();
        }
        else
        {
            return default(T);
        }
    }
}

I know it needs where T : new() for those using new T(). This question is, how to judge this on runtime?

like image 685
Junle Li Avatar asked Aug 08 '14 06:08

Junle Li


People also ask

What does where T new () mean?

where T : new() Means that the type T must have a parameter-less constructor. Having this constraint will allow you to do something like T field = new T(); in your code which you wouldn't be able to do otherwise.

What is new () constraint in C#?

The new constraint specifies that a type argument in a generic class or method declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.

What is the keyword which is used to apply constraints on type parameter?

Object, you'll apply constraints to the type parameter. For example, the base class constraint tells the compiler that only objects of this type or derived from this type will be used as type arguments. Once the compiler has this guarantee, it can allow methods of that type to be called in the generic class.

What are generics in c# net?

Generics allow you to define the specification of the data type of programming elements in a class or a method, until it is actually used in the program. In other words, generics allow you to write a class or method that can work with any data type.


4 Answers

I little played with MarcoLaser's answer and made my 'if T is newable then get instance constructor'

public class MyClass<T>
{
        public MyClass()
        {
            var constructor = typeof(T).GetConstructor(Type.EmptyTypes);
            if (constructor != null)
                Data = (T)constructor.Invoke(null);  
        }

        public T Data { get; set; }
}



  
like image 176
Mustafa Akçakaya Avatar answered Oct 12 '22 08:10

Mustafa Akçakaya


You just need to check whether the type has a parameterless constructor. You do it by callingType.GetConstructor method with empty types as parameter.

var constructorInfo = typeof(T).GetConstructor(Type.EmptyTypes);
if(constructorInfo != null)
{
   //here you go
   object instance = constructorInfo.Invoke(null);
}
like image 41
Sriram Sakthivel Avatar answered Oct 12 '22 10:10

Sriram Sakthivel


If I remember correctly, Activator.CreateInstance<T> will return an object constructed with the parameterless constructor if T is a class or a default(T) if T is a struct.

You can use the technique in Sriram's answer to first make sure a parameterless constructor exists for T.

like image 7
Theodoros Chatzigiannakis Avatar answered Oct 12 '22 10:10

Theodoros Chatzigiannakis


You could something like checking for a default constructor and execute new T() if one is found. To do this you could use something like:

var constructor = typeof(T).GetConstructor(Type.EmptyTypes);
if(constructor != null)
{
    return (T)constructor.Invoke(null);
}
else
{
    return default(T);
}
like image 1
MarcoLaser Avatar answered Oct 12 '22 09:10

MarcoLaser