[英]Can I dynamically specify the type when creating an instance of a generic interface?
I have got a bit stuck with working out how to pass a data object to its processor class. 我在研究如何将数据对象传递到其处理器类时有些困惑。 I have attempted to give a simplified example of the problem below.
我试图在下面给出一个简化的例子。 I'm trying to figure out if there is a type safe way to instantiate the processor using the generic interface?
我试图找出是否存在使用泛型接口实例化处理器的类型安全的方法?
Cheers, 干杯,
Charlie 查理
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();
}
First option - you can just use dynamic
(not strongly typed) 第一种选择-您可以只使用
dynamic
(不是强类型)
dynamic instance = Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
If you need compile time checks you'll have to go non-generic interface OR generic method that uses generic interface. 如果需要编译时检查,则必须使用非通用接口或使用通用接口的通用方法。 The reason is
IFoo<OneType>
and IFoo<OtherType>
are not related by inheritance so there is no common static type you can refer to both. 原因是
IFoo<OneType>
和IFoo<OtherType>
通过继承不相关,因此没有可以同时引用的静态类型。
Sample for non-generic interface: 非通用接口的示例:
interface IDescribeSomething
{
void Process(SomeBaseType type);
}
IDescribeSomething instance =
(IDescribeSomething)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
Sample for generic + base similar to IEnumrable<T>
. 类似于
IEnumrable<T>
通用+基本示例。 Note that it generally does not solve your problem but at least some other places can have generic code: 请注意,它通常不能解决您的问题,但是至少其他一些地方可以具有通用代码:
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)
Sample of strongly typed generic method 强类型泛型方法样本
void DoProcess<T>(T task)
{
IDescribeSomething<T> instance =
(IDescribeSomething<T>)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
}
You can invoke this method by using MakeGenricMethod
- How do I use reflection to call a generic method? 您可以使用
MakeGenricMethod
调用此方法- 如何使用反射调用泛型方法?
Do you want something like this ? 你想要这样的东西吗?
public void Process<T>(T type) where T : ICommon
{
Console.WriteLine("Processing {0}", type.GetType());
}
public interface ICommon
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.