Factory класс, возвращающий общий интерфейс

У меня мало конкретных, которые используют следующий тип интерфейса

interface IActivity<T>
{
    bool Process(T inputInfo);
}

Конкретные классы выглядят следующим образом

class ReportActivityManager :IActivity<DataTable>
{
    public bool Process(DataTable inputInfo)
    {
        // Some coding here
    }
}

class AnalyzerActivityManager :IActivity<string[]>
{
    public bool Process(string[] inputInfo)
    {
        // Some coding here
    }
}

Теперь, как я могу написать класс factory, который перенастраивает общий интерфейс, что-то вроде IActivity.

class Factory
{
    public IActivity<T> Get(string module)
    {
        // ... How can i code here
    }
}

Спасибо

Ответ 1

Вы должны создать общий метод, иначе компилятор не будет знать тип T в возвращаемом значении. Когда у вас будет T, вы сможете создавать активность по типу T:

class Factory
{
    public IActivity<T> GetActivity<T>()
    {
        Type type = typeof(T);
        if (type == typeof(DataTable))
            return (IActivity<T>)new ReportActivityManager();
        // etc
    }
}

Использование:

IActivity<DataTable> activity = factory.GetActivity<DataTable>();

Ответ 2

Часто это реализуется, как в лазыберовском ответе. В С++ вы можете использовать специализированную специализацию для получения ошибок компилятора при попытке создать тип, который не обрабатывает factory.

Вы не можете сделать это на С#, но можете приблизиться. Хотя код может показаться немного удивительным, что, в свою очередь, может быть проблемой.

public static class Factory {
   public static IActivity<someType> Get(this someType self){
          //stuff specific to someType
   }

   public static IActivity<someOtherType> Get(someOtherType self){
          //stuff specific to someOtherType
   }

   public static T Creator<T>(){
        return null;
   }

}

Тогда использование будет

IActivity<someType> act = Factory.Creator<someType>().Get(); 

конечно, это работает только в том случае, если вы можете передать конкретный тип. Если вам нужно передать параметр типа, все усложняется.