Reputation: 54541
I would like to do some similar process within a loop like this by calling a generic method with different types.
AAA
, BBB
are all classes. CreateProcessor
is a generic method in the class of MyProcessor
.
new List<Type> {typeof (AAA), typeof (BBB)}.ForEach(x =>
{
var processor = MyProcessor.CreateProcessor<x>(x.Name);
processor.process();
});
This doesn't compile, I got the error saying Cannnot resolve symbol x
.
Technically, how to achieve it? (I know the strategy pattern is better...)
Upvotes: 6
Views: 241
Reputation: 2954
This is how you would create a new variable using only type information, by using dynamic
you are able to call any method which you know exists for all of the types. I would suggest (assuming these types are your own classes) you implement an interface baseclass or something for these if possible, it simplify your quite a lot...
new List<Type> { typeof(string), typeof(int) }.ForEach(x =>
{
dynamic processor = Activator.CreateInstance(x);
processor.ToString();
processor.CallAnyMethodHere();
processor.Process();
});
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
public class mainClass
{
public static void Main(string[] args)
{
new List<Type> { typeof(StringBuilder), typeof(Int64) }.ForEach(x =>
{
dynamic instance = Activator.CreateInstance(x);
DoSomething(instance);
});
Console.ReadKey();
}
public static void DoSomething(StringBuilder stringBuilder)
{
Console.WriteLine("StringBuilder overload");
}
public static void DoSomething(Int64 int64)
{
Console.WriteLine("Int64 overload");
}
}
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Linq;
public class mainClass
{
public static void Main(string[] args)
{
new List<Type> { typeof(StringBuilder), typeof(Int64) }.ForEach(x =>
{
var methodInfoArray = typeof(mainClass).GetMethods();
var methodInfo = methodInfoArray.First(mi => mi.Name == "DoSomething" && mi.IsGenericMethodDefinition);
var genericMethod = methodInfo.MakeGenericMethod(new Type[] { x });
var blah = genericMethod.Invoke(null, new object[] { "Hello" }) as MethodInfo;
});
Console.ReadKey();
}
public static void DoSomething<T>(string variable)
{
Console.WriteLine("DoSomething<T> " + typeof(T) + " overload - " + variable);
}
public static void DoSomething(string variable)
{
Console.WriteLine("DoSomething - " + variable);
}
}
Upvotes: 0
Reputation: 125650
Sorry, I updated my question. I intended to call a generic method actually.
var method = typeof(MyProcessor).GetMethod("CreateProcessor", new Type[] { typeof(string) });
new List<Type> { typeof(AAA), typeof(BBB) }.ForEach(x =>
{
dynamic processor = method.MakeGenericMethod(x).Invoke(null, new[] { x.Name });
processor.process();
});
Upvotes: 7
Reputation: 942488
Reflection is required to deal with the Type class:
new List<Type> { typeof(AAA), typeof(BBB) }.ForEach(x => {
var type = typeof(MyClass<>).MakeGenericType(x);
dynamic processor = Activator.CreateInstance(type, x.Name);
processor.process();
});
Upvotes: 8
Reputation: 19526
You have to use reflection to create a generic object like that. This page from Microsoft has an excellent rundown on what you need to do: How to: Examine and Instantiate Generic Types with Reflection
Upvotes: 0