Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: Generic types that have a constructor?

Tags:

c#

generics

I have the following C# test code:

  class MyItem
  {
    MyItem( int a ) {}
  }

  class MyContainer< T >
    where T : MyItem, new()
  {
    public void CreateItem()
    {
      T oItem = new T( 10 );
    }
  }

Visual Studio can't compile it, the error is at line where 'new' is used:

'T': cannot provide arguments when creating an instance of a variable type

Is it possible in C# to create an object of generic type with non-parameterless constructor? It's no problem to do such thing in C++ templates, so i'm very curious why i can't do same thing in C#. Maybe some additional 'where' is required or syntax is different?

like image 930
grigoryvp Avatar asked Nov 30 '09 19:11

grigoryvp


2 Answers

C#, and VB.Net for that matter, do not support the notion of constraining a generic to have a constructor with specific parameters. It only supports constraining to have an empty constructor.

One work around is to have the caller pass in a factory lambda to create the value. For instance

public void CreateItem(Func<int,T> del) {
  T oItem = del(10);
}

Call site

CreateItem(x => new SomeClass(x));
like image 89
JaredPar Avatar answered Oct 01 '22 09:10

JaredPar


It can be done with reflection:

public void CreateItem()
{
  int constructorparm1 = 10;
  T oItem = Activator.CreateInstance(typeof(T), constructorparm1) as T;
}

But there is no generic constraint to ensure that T implements the desired constructor, so I wouldn't advise doing this unless you are careful to declare that constructor in every type that implements the interface.

like image 28
Greg Avatar answered Oct 01 '22 09:10

Greg