fl4izdn4g
fl4izdn4g

Reputation: 35

How to create generic method which return instance of generic?

I want to create simple factory class which implements interface like this:

IFactory 
{
   TEntity CreateEmpty<TEntity>(); 
}

In this method I want to return an instance of type TEntity (generic type). Example:

TestClass test = new Factory().CreateEmpty<TestClass>(); 

Is it possible? Does interface is correct?

I've tried something like this:

private TEntity CreateEmpty<TEntity>() {
   var type = typeof(TEntity);
   if(type.Name =="TestClass") {
      return new TestClass();
   }
   else {
     ...
   }
}

But it doesn't compile.

Upvotes: 1

Views: 2687

Answers (3)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112342

You need to specify the new() constraint on the generic type parameter

public TEntity CreateEmpty<TEntity>() 
    where TEntity : new()
{
    return new TEntity();
}

The new constraint specifies that the concrete type used must have a public default constructor, i.e. a constructor without parameters.

public TestClass
{
    public TestClass ()
    {
    }

    ...
}

If you don't specify any constructors at all, then the class will have a public default constructor by default.

You cannot declare parameters in the new() constraint. If you need to pass parameters, you will have to declare a dedicated method for that purpose, e.g. by defining an appropriate interface

public interface IInitializeWithInt
{
     void Initialize(int i);
}

public TestClass : IInitializeWithInt
{
     private int _i;

     public void Initialize(int i)
     {
         _i = i;
     }

     ...
}

In your factory

public TEntity CreateEmpty<TEntity>() 
    where TEntity : IInitializeWithInt, new()
{
    TEntity obj = new TEntity();
    obj.Initialize(1);
    return obj;
}

Upvotes: 6

igofed
igofed

Reputation: 1442

This method will help you, pass parameters in that order, in which they in constructor:

private T CreateInstance<T>(params object[] parameters)
{
    var type = typeof(T);

    return (T)Activator.CreateInstance(type, parameters);
}

Upvotes: 2

FiftiN
FiftiN

Reputation: 797

interface IFactory<TEntity> where T : new()
{
   TEntity CreateEmpty<TEntity>(); 
}

Upvotes: 2

Related Questions