Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When we should use new() keyword when inherited from generic class?

Tags:

c#

generics

I read an training article about generic class, it has some code like this :

public class ValidationBase {
  public virtual bool IsValidName(string name) {
    return name.Length > 5;
  }
}

 public class LogicBase<T> where T : ValidationBase, new() {
    private T _Validations = default(T);
      public T Validations {
        get {
          if (_Validations == null) {
            _Validations = new T();
           }
        return _Validations;
          }
       set { _Validations = value; }
      }
}

it said that :

The new keyword creates an instance of the DataModelBase class by default if no specific type has been provided for T

I really don't understand when we should use new() keyword?

NOTE: if edit above code like this:

 public class LogicBase<T> where T : ValidationBase

instead of

 public class LogicBase<T> where T : ValidationBase, new()

what will happen?

like image 589
pejman Avatar asked Dec 20 '22 14:12

pejman


1 Answers

When specifying a generic class, new() acts as a constraint against the type that T can be.

In this case, new() is stating that the type of T must be a class with a public, parameterless constructor.

For instance:

public class MyGenericClass<T> where T : new()
{
}

public class MyClass
{
    public MyClass()
    {
    }
}

public class MyClass2
{
    public MyClass2(int i)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        // OK!
        MyGenericClass<MyClass> c1 = new MyGenericClass<MyClass>();

        // Gives the error:
        // 'MyClass2' must be a non-abstract type with a public parameterless
        // constructor in order to use it as parameter 'T' in the generic type
        // or method 'MyGenericClass<T>'
        MyGenericClass<MyClass2> c2 = new MyGenericClass<MyClass2>();
    }
}

This is so that you can create a new instance of type T using new T(). As this is generic, all types of T must conform to the same rules. where T: new() forces all types of T to have a public, parameterless constructor.

You code:

if (_Validations == null) {
    _Validations = new T();
}

creates a new instance of T. As T could be anything, all types of T must therefore be able to be created using new MyType().

like image 84
rhughes Avatar answered Jan 19 '23 00:01

rhughes