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 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.
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>
. 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?
Do you want something like this ?
public void Process<T>(T type) where T : ICommon
{
Console.WriteLine("Processing {0}", type.GetType());
}
public interface ICommon
{
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.