Reputation: 1318
i have two classes: Class1
and Class2
class Class1
{
public void method();
}
class Class2
{
public void method();
}
in another place I have the class type and I want to create an instance from it.
type is typeof(Class1
) or typeof(Class2)
public void CreateInstance(Type type)
{
var instance = Activator.GetInstance(type);
instance.method(); //compile error: object doesn't contain method
}
a solution is I define an interface that my classes implement that interface.
interface IInterface
{
void method();
}
public void CreateInstance(Type type)
{
var instance = Activator.GetInstance(type);
((IInterface)instance).method();
}
because I can't access to class definition I can't do this. How can I do this?
Upvotes: 0
Views: 79
Reputation: 131180
You can avoid reflection and performance issues entirely by using a generic method and dynamic
:
public void CreateInstance<T>() where T:new()
{
dynamic instance=new T();
instance.method();
}
Which you can call simply by passing the type:
CreateInstance<Class1>();
CreateInstance<Class2>();
Type safety is lost either when using reflection or using dynamic
. Checking for the existence of a method with reflection isn't any safer or less risky than having the runtime throw an exception - in both cases you have to handle an exceptional condition. What are you going to do when this exception occurs?
With dynamic
, a missing method will raise a RuntimeBinderException specifying that a method is missing. If I changed the method call from method
to method1
I'll get an exception saying:
'ConsoleApplication24.Class1' does not contain a definition for 'method1'
This way the code does not pay the reflection penalty for the normal cases. This is also safer - there is no way that the exception can be missed.
The only way that provides compile-type safety is to have the classes implement an interface and use it as a generic constraint, eg:
public static void CreateInstance<T>() where T : ISomething, new()
{
var instance = new T();
instance.method();
}
Upvotes: 1
Reputation: 4360
Best option would be to use interface for safety. But if you can't do that, you can invoke this method through reflection:
public class MyClass
{
public void Method()
{
Console.WriteLine("executed");
}
}
public class MyActivator
{
public static void CreateInstance(Type type)
{
var instance = Activator.CreateInstance(type);
var method = GetMethod("method");
method.Invoke(instance, null);
}
}
And then you call this by:
MyActivator.CreateInstance(typeof(MyClass));
Remember to add some checking if method is not null
Upvotes: 0
Reputation: 117019
This is what you need:
public void CreateInstance(Type type)
{
var instance = Activator.CreateInstance(type);
type.GetMethod("method").Invoke(instance, null);
}
Or, alternatively, use dynamic
:
public void CreateInstance(Type type)
{
dynamic instance = Activator.CreateInstance(type);
instance.method();
}
NB: You had GetInstance
instead of CreateInstance
in your code, but I corrected it.
Upvotes: 4