2012-05-05 2 views
0

Я хочу создать простой класс фабрики, который реализует интерфейс, как это:Как создать общий метод, возвращающий экземпляр generic?

IFactory 
{ 
    TEntity CreateEmpty<TEntity>(); 
} 

В этом методе я хочу вернуть экземпляр типа TEntity (общего типа). Пример:

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

Возможно ли это? Правильно ли работает интерфейс?

Я пытался что-то вроде этого:

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

Но он не компилируется.

ответ

6

Вы должны указать new() ограничение на параметр универсального типа

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

Новое ограничение указывает, что конкретный используемый тип должен иметь конструктор по умолчанию, то есть конструктор без параметров.

public TestClass 
{ 
    public TestClass() 
    { 
    } 

    ... 
} 

Если вы вообще не укажете каких-либо конструкторов, то по умолчанию у класса будет стандартный конструктор по умолчанию.

Вы не можете объявлять параметры в ограничении new(). Если вам нужно передать параметры, вам придется объявить выделенный для этой цели метод, например. определив соответствующий интерфейс

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

public TestClass : IInitializeWithInt 
{ 
    private int _i; 

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

    ... 
} 

В вашем заводе

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

Спасибо для всестороннего ответа. – fl4izdn4g

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

Этот метод поможет вам, передавать параметры в том порядке, в котором они в конструкторе:

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

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