在创建通用接口的实例时,我可以动态指定类型吗?

时间:2014-01-08 17:20:14

标签: c# generics interface

我对如何将数据对象传递给它的处理器类感到困惑。我试图给出下面问题的简化示例。我试图弄清楚是否有一种类型安全的方法来使用通用接口来实例化处理器?

干杯,

查理

class APieceOfState
    {
        public string AbitOfData { get; set; }
    }

interface IDescribeSomething<in T> 
    {
        void Process(T type) ;
    }


 class ImplementWhatIsDescribed : IDescribeSomething<APieceOfState>
    {
        public void Process(APieceOfState type)
        {
            Console.WriteLine("Processing {0}", type.GetType());
        }

    }

 private static void Main(string[] args)
    {
        var nextTest = new ImplementWhatIsDescribed();
        var newStateObj = new APieceOfState();
        nextTest.Process(newStateObj);

        // Map processor to data in a dictionary
        var dic = new Dictionary<Type, Type>();
        var task = new APieceOfState();
        var taskProcessor = new ImplementWhatIsDescribed();
        dic.Add(task.GetType(), taskProcessor.GetType());

        // Lookup processor using data type
        Type lookupProcessorType;
        dic.TryGetValue(task.GetType(), out lookupProcessorType);

        //                                   vvvvvvvvvvv - How can I make this dynamic based on task.GetType()  ?
        var instance = (IDescribeSomething<APieceOfState>)Activator.CreateInstance(lookupProcessorType);
        instance.Process(task);

        Console.ReadKey();
    }

2 个答案:

答案 0 :(得分:1)

第一个选项 - 您可以使用dynamic(非强类型)

dynamic instance = Activator.CreateInstance(lookupProcessorType);
instance.Process(task);

如果需要编译时检查,则必须使用通用接口的非通用接口或通用方法。原因是IFoo<OneType>IFoo<OtherType>与继承无关,因此没有可以引用两者的常见静态类型。

非通用接口的示例:

interface IDescribeSomething
{
   void Process(SomeBaseType type);
}


IDescribeSomething instance = 
    (IDescribeSomething)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);

类似于IEnumrable<T>的通用+基类的示例。请注意,它通常不能解决您的问题,但至少其他一些地方可以使用通用代码:

interface IDescribeSomething
{
   void Process(SomeBaseType type);
}

interface IDescribeSomething<T> : IDescribeSomething
{
   void Process(T type);
}

class APieceOfState : SomeBaseType {}

class ImplementWhatIsDescribed : IDescribeSomething<APieceOfState>
{
    public void Process(SomeBaseType type)
    {
        Process((APieceOfState)type);
    }
    public void Process(APieceOfState type)
    {
        Console.WriteLine("Processing {0}", type.GetType());
    }

}

IDescribeSomething instance = 
     (IDescribeSomething)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);

// but in this case you can sometime write strongly type one too
// if you got strongly typed version of interface 
IDescribeSomething<APieceOfState> p =...
p.Process(task)

强类型泛型方法的示例

void DoProcess<T>(T task)
{
   IDescribeSomething<T> instance = 
     (IDescribeSomething<T>)Activator.CreateInstance(lookupProcessorType);
   instance.Process(task);

}

您可以使用MakeGenricMethod - How do I use reflection to call a generic method?

调用此方法

答案 1 :(得分:0)

你想要这样的东西吗?

public void Process<T>(T type) where T : ICommon
{
    Console.WriteLine("Processing {0}", type.GetType());
}

public interface ICommon
{

}