create exact instance from class name - c#

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?

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.

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();
}

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

Related

How to cast object to its actual type

Consider the following piece of code:
class MyClass
{
}
class MyClass2 : MyClass
{
}
private void Foo(MyClass cl)
{
//cl is actually MyClass2 instance
TestGeneric(cl);
}
private void TestGeneric<T>(T val)
{
//do smth
}
After calling Foo(), the T in TestGeneric is MyClass, not MyClass2.
How do I achieve treating val as a MyClass2 instance?
Thanks in advance.
Upd:
I don't actually know that the object has been created using MyClass2 ctor, but rather can infer this by calling val.GetType() so a simple as MyClass2 won't work
It can be done with a visitor pattern. It is a nice object oriented approach, when you have all handling code in a single handler class (not in each message) and if more message types will be needed, just add additional handler methods.
// Your message classes
public class MyClass : IMessage
{
// Implement acceptance of handler:
public void AcceptHandler(IMessageHandler handler)
{
handler.HandleMessage(this);
}
}
public class MyClass2 : MyClass
{
// Nothing more here
}
// Define interface of message
public interface IMessage
{
void AcceptHandler(IMessageHandler handler)
}
// Define interface of handler
public interface IMessageHandler
{
// For each type of message, define separate method
void HandleMessage(MyClass message)
void HandleMessage(MyClass2 message)
}
// Implemente actual handler implementation
public class MessageHandler : IMessageHandler
{
// Main handler method
public void HandleSomeMessage(MyClass message) // Or it could be IMessage
{
// Pass this handler to message. Since message implements AcceptHandler
// as just passing itself to handler, correct method of handler for MyClass
// or MyClass2 will be called at runtime.
message.AcceptHandler(this);
}
public void HandleMessage(MyClass message)
{
// Implement what do you need to be done for MyClass
}
public void HandleMessage(MyClass2 message)
{
// Implement what do you need to be done for MyClass2
// If code of MyClass should be run too, just call
// this.HandleMessage((MyClass)message);
}
}
Assuming you can change Foo, but not its signature, you could do this:
private void Foo(MyClass cl)
{
TestGeneric((dynamic)cl);
}
This will resolve the version of TestGeneric that gets called at runtime instead of at compile time, calling TestGeneric<MyClass2> when cl is of that type.
Well when you call a generic method, the type parameters will be resolved based on the types of the variables, and not based on the types of the actual values.
So for example if you have:
var x = int as object;
Foo(x);
and then you have this:
void Foo<T>(T value)
{
}
Then the type of T will be object and not int, because that's the type of the variable.
A possible solution would be to dynamically cast the value to the lowest subclass, using either reflection or a compiled expression.
Some other alternatives you have are to use reflection to check the actual type of the value that was passed and base your logic on that, or use other language mechanics such as virtual methods.
If you describe the scenario you are trying to solve, someone could probably suggest a suitable solution.
(Answering the question from the comment)
It's a bulky solution, and you are depending on concrete implementations, but you could do something along these lines:
//initialization
Dictionary<Type, Action> typeActions = new Dictionary<Type, Action>();
typeActions.Add(typeof (MyClass), () => {Console.WriteLine("MyClass");});
typeActions.Add(typeof (MyClass2), () => {Console.WriteLine("MyClass2");});
private void TestGeneric<T>(T val)
{
//here some error checking should be in place,
//to make sure that T is a valid entry class
Action action = typeActions[val.GetType()];
action();
}
A downside to this approach is that it depends on the variables being exactly of type MyClass or MyClass2, so if someone later adds another level of inheritance, this will break, but still, it's more flexible than a if-else or a switch in the generic method.
A cast is when you know more about the type of an object than the compiler is able to deduce from the static code.
This leaves you with two options when ever you need more type information that you currently have.
Change the declaration to make the information explicit at declaration
Make a cast
or go dynamic
In your case the first would require changing Foo to be generic too
private void Foo<T>(T cl)
{
//cl is actually MyClass2 instance
TestGeneric(cl);
}
The second option would require casting and I'm guessing you have multiple types so you'll need a lot of if-else-if's which is generally a bad sign especially when the condition is based on the type of an object
private void Foo(MyClass cl)
{
var mc2 = tcl as MyClass2;
if(mc2 != null) {
TestGeneric(mc2);
return;
}
var mc3 = tcl as MyClass3;
if(mc3 != null) {
TestGeneric(mc3);
return;
}
throw new InvalidOperationException("Type not recognised");
}
lastly you could go dynamic
private void TestDynamic(dynamic val)
{
TestGeneric(val);
}
There are other ways of doing it dynamically such as runtime generating code but it's a lot easier to simply use the DLR than trying to role your own on
You don't want to call a generic method here. Once you enter TestGeneric<T>, even if T is MyClass2 as you want, you can't have written any code against MyClass2 (or even MyClass, unless you add a restriction on T) so it doesn't help!
You certainly don't need to go down the route of reflection or dynamic.
Most obvious way to do this: put the class-specific behaviour in the class itself:
class MyClass
{
public virtual void Test()
{
// Behaviour for MyClass
}
}
class MyClass2 : MyClass
{
public override void Test()
{
// Behaviour for MyClass2
}
}
private void Foo(MyClass cl)
{
cl.Test();
}
Next-best: branch code depending on the type passed:
private void Foo(MyClass cl)
{
if (cl is MyClass2)
{
Test((MyClass2)cl);
}
else
{
Test(cl);
}
}
private void Test(MyClass cl)
{
// Behaviour for MyClass
}
private void Test(MyClass2 cl2)
{
// Behaviour for MyClass2
}
In both these cases you can write code directly against MyClass2 (or MyClass) without having to do any reflection, use dynamic, or... whatever you were planning to do in your generic method - branch on typeof(T)?
Best solution would be to change Foo method to be generic too, so that you can save type information. You should do this like so:
private void Foo<T>(T cl) where T : MyClass
{
TestGeneric(cl);
}
Otherwise, you would have an example of bad design. Simple way out would be
private void Foo(MyClass cl)
{
if (cl is MyClass2)
TestGeneric((MyClass2)cl);
else
TestGeneric(cl);
}
You could also do a broader solution using reflection, but that would be abuse of tools to patch bad design.
Following would be a reflection based solution, but I did not run it so bear with me and try to fix possible errors.
private void Foo(MyClass cl)
{
Type genMethodType = typeof(TestGenericMethodClass);
MethodInfo genMethod = genMethodType.GetMethod("TestGeneric");
MethodInfo methodConstructed = genMethod.MakeGenericMethod(cl.GetType());
object[] args = new object[] { cl };
methodConstructed.Invoke(instanceOfTestGenericMethodClass, args);
}
So
Get type of class in which your TestGeneric method is defined
Use Type.GetMethod to retrieve method definition
Retrieve actual type of your cl variable to construct generic method
Use MethodInfo.MakeGenericMethod to construct a method for specific type
Use MethodBase.Invoke to invoke constructed method
Your code will differ based on your current implementation (depending on type names, method accessibility and such).

Generic question... Calling a static method from a generic class

I have a generic class:
public class MyList<LinkedItem> : List<LinkedItem> where LinkedItem : MyItem, new()
{
}
From that generic class, I would like to access a static function from the LinkedItem Class which is a descendant of MyItem class. (thus without creating an instance of the LinkedItem).
Is it possible?
Thank you,
Eric
Yes, it is possible, but you have to use reflection by obtaining a MethodInfo from typeof(T).GetMethod("Foo", BindingFlags.Public | BindingFlags.Static) and then calling Invoke on it.
It can be very useful, particularly if using the same technique on a ConstructorInfo rather than a MethodInfo, to create a generic factory that uses parameters in the constructor. It is though one to use sparingly. In particular, there is no way of guaranteeing at compile time that the type in question has a static method of the required signature, so type-safety is gone and such an error won't be caught until run-time.
It can be done through reflection. There's no straight forward way to do it since C# has no API constraints on static memebers.
I am not sure what is the scenario you're in, but in most cases this is not a recommended solution :)
public class MyList<LinkedItem> : List<LinkedItem>
where LinkedItem : MyItem, new()
{
public int CallStaticMethod()
{
// Getting a static method named "M" from runtime type of LinkedItem
var methodInfo = typeof(LinkedItem)
.GetMethod("M", BindingFlags.Static | BindingFlags.Public);
// Invoking the static method, if the actual method will expect arguments
// they'll be passed in the array instead of empty array
return (int) methodInfo.Invoke(null, new object[0]);
}
}
public class MyItem
{
}
class MyItemImpl : MyItem
{
public MyItemImpl()
{
}
public static int M()
{
return 100;
}
}
So, for example the next code will print 100:
public void Test()
{
Console.WriteLine(new MyList<MyItemImpl>().CallStaticMethod());
}
No this is not possible directly from the type parameter because you cannot invoke static methods on generic type parameters (C# Lang Spec section 4.5).
A type parameter cannot be used in a member access (§7.5.4) or type name (§3.8) to identify a static member or a nested type.
Yes this is possible to achieve via reflection tricks as other people noted. But generally speaking using reflection to solve a simple method invocation scenario is an indication of bad design.
A much better design would be to pass a factory / delegate around which encapsulates the static method in a type safe manner.
class MyItem : MyItem {
static void TheFunction() { ... }
}
public class MyList<LinkedItem> : List<LinkedItem> where LinkedItem : MyItem, new()
{
public MyList(Action theStaticFunction) {
...
}
}
new MyList<MyItem>(MyItem.TheFunction);
This isn't possible. There's no way to declare a constraint on the LinkedItem parameter that says that it must contain the static method in question.
Possibly the closest you'll get is:
public class ILinkedItemFactory<T>
{
void YourMethodGoesHere();
}
public class MyList<LinkedItem, Factory> : List<LinkedItem>
where Factory : ILinkedItemFactory<LinkedItem>
where LinkedItem : MyItem, new()
{
public MyList(Factory factory)
{
factory.YourMethodGoesHere();
}
}
This is, by default, not possible. However, if you know the name of the method you want to invoke, and you are positive that every LinkedItem type will contain this method, you can use reflection to reach your goal. Note: there's often a better way than resolving to reflection for general programming tasks.
The following will always output true for DoSomething. It invokes a static member that's always available (I removed your generic type constraint, as that's not important with static methods).
public class MyList<LinkedItem> : List<LinkedItem>
{
public bool DoSomething()
{
Type t = typeof(LinkedItem);
object o = new Object();
var result = t.InvokeMember("ReferenceEquals",
BindingFlags.InvokeMethod |
BindingFlags.Public |
BindingFlags.Static,
null,
null, new[] { o, o });
return (result as bool?).Value;
}
}
// call it like this:
MyList<string> ml = new MyList<string>();
bool value = ml.DoSomething(); // true
PS: meanwhile, while I typed this, others seem to suggest the same approach ;-)
This is completely possible though not directly in the way you are stating without maybe reflection. You would want to implement a non-static access method in the baseclass and have it overridden in every specific inheriting class.
public class MyItem
{
public static void DoSomeStaticStuff() { //DoSomeStaticStuff for MyItem }
public virtual void AccessSomeStaticStuff() { MyItem.DoSomeStaticStuff(); }
}
public class SomeItem : MyItem
{
public static void DoSomeStaticStuff() { //DoSomeStaticStuff for SomeItem }
public override void AccessSomeStaticStuff() { SomeItem.DoSomeStaticStuff(); }
}
Then in your class which has the constraint where T : MyItem you would just call T.AccessSomeStaticStuff();

Call a method of type parameter

Is there any way to do code such this:
class GenericClass<T>
{
void functionA()
{
T.A();
}
}
Or, how to call a function of type parameter (type is some my custom class).
Re:
T.A();
You can't call static methods of the type-parameter, if that is what you mean. You would do better to refactor that as an instance method of T, perhaps with a generic constraint (where T : SomeTypeOrInterface, with SomeTypeOrInterface defining A()). Another alternative is dynamic, which allows duck-typing of instance methods (via signature).
If you mean that the T is only known at runtime (as a Type), then you would need:
typeof(GenericClass<>).MakeGenericType(type).GetMethod(...).Invoke(...);
To call a method of a generic type object you have to instantiate it first.
public static void RunSnippet()
{
var c = new GenericClass<SomeType>();
}
public class GenericClass<T> where T : SomeType, new()
{
public GenericClass(){
(new T()).functionA();
}
}
public class SomeType
{
public void functionA()
{
//do something here
Console.WriteLine("I wrote this");
}
}
I think you are looking for generic type constraints:
class GenericClass<T> where T : MyBaseClass
{
void functionA<T>(T something)
{
something.A();
}
}
In terms of the code you posted - in order to call something on T, you will need to pass it as a parameter to functionA. The constraint you use will have to ensure that any T has an A method that can be used.
I understand from your code that you want to call a type parameter static method, and that's just impossible.
See here for more info : Calling a static method on a generic type parameter

C# Generics - Constraints on type parameters

I'm trying to build a factory method that uses the generics feature of C#.
In this factory method I would like to constraint it to some specific classes, all of which do not have a default constructor.
Here is my example. Can someone tell me if it's possible to run it?
public class AbstractClass {
//this abstract class does not have a default constructor, nor its subclasses
public AbstractClass(SomeClassName obj) {
//use obj for initialization
}
}
//this factory class should create objects of type T that inherit
//from AbstractClass and invoke the non-default constructor
public class FactoryClass {
public static T BuildObject<T> (SomeClassName obj) where T: AbstractClass {
return new T(obj); //does not work?!?!?!
}
}
//Edit: ANSWER!!!
public static T BuildObject<T>(SomeClassUsedForTheConstructor item) where T : SomeAbstractClass {
return (T) Activator.CreateInstance(typeof (T), item);
}
I like to use Activator.CreateInstance(typeof(T)) in my generics that need to create new objects of type T. It works really well.
Look at the Type class and GetConstructor. Once you get the ConstructorInfo object, use the Invoke Method.
var x = typeof(T);
var t = x.GetConstructor(new[] {obj.GetType()});
object u = t.Invoke(<inputs>);
I don't think you can instantiate generic types without a default constructor on the constraint type.
Consider instead specifying an interface IAbstractClass, such that your factory class can set the SomeClassName parameter as a property of IAbstractClass.
Additionally, if a SomeClassName instance is required for initializing AbstractClass, consider also having an empty default constructor, but a rich initializer method defined in IAbstractClass. For example:
public interface IAbstractClass { void Initialize(SomeClassName obj); }
That way, your static BuildObject method instead does:
public static T BuildObject<T>(SomeClassName obj) where T: AbstractClass
{
T newObject = new T();
IAbstractClass ac = newObject as IAbstractClass;
ac.Initialize(obj);
}
No, what you are trying to do is not possible using the built-in generic constraints alone. The new keyword only allows you to constrain the generic type to having a default constructor.

Calling a generic interface

public interface IProcessor<T>
{
void Process(T instance);
}
foreach(AbstractType instance in myClass.SomeCollection)
OnProcess(instance);
public void OnProcess<T>(T instance)
{
IProcessor<T> processor =
unityContainer.Resolve<IProcessor<T>>();
processor.Process(instance);
}
The problem with this code is that the in OnProcess is always AbstractType, and not the concrete type of the instance being passed. I currently see two possibilities.
01: Create a non generic IProcessor and use it as the base for IProcessor. Any implementor will have to implement both generic and non-generic Process methods, typically typecasting and passing onto the generic method.
02: Use Type.MakeGenericType to get the IProcessor, resolve that, and then use reflection to invoke the Process method.
Both of these approaches feel a bit "unclean". Can anyone think of a way I can do this without having to resort to these practices?
Thanks
Pete
2 will be a performance killer (the necessary dynamic/relection invoke in particular is slow)
1 is a common answer to this problem, especially with explicit implementation; the problem is getting hold of the type... does unity allow query with a Type instance, rather than via generics? If so something like below... of course, you might still have to use MakeGenericType:
Type intType = typeof(IProcessor<>).MakeGenericType(instanceType);
IProcessor proc = (IProcessor) IoC.Resolve(intType);
Where instanceType is perhaps via instance.GetType(). For similar reasons, it might be helpful to expose the T as a Type on the IProcessor:
public interface IProcessor
{
void Process(object instance);
Type InstanceType {get;}
}
public interface IProcessor<T> : IProcessor
{
void Process(T instance);
}
class SomeClass: IProcessor<int>
{
public void Process(int instance)
{
throw new NotImplementedException();
}
Type IProcessor.InstanceType {get {return typeof(int);}}
void IProcessor.Process(object instance)
{
Process((int)instance);
}
}
Of course, an (optional) base-class might allow you to avoid some of this per-implementation:
abstract class SomeBase<T> : IProcessor<T>
{
public void Process(T instance)
{
OnProcess(instance);
}
Type IProcessor.InstanceType {get {return typeof(T);}}
void IProcessor.Process(object instance)
{
Process((T)instance);
}
protected abstract void OnProcess(T instance);
}
If I understand your problem, you want to call a process that's dependent on 2 types (the type of processor, and the object being processed). Is that right? If that's the case, you can use a multi-method pattern for this kind of problem. Here's an example:
public interface IProcessor
{
void Process( IThingToProcess p ); // Will call p.ProcessMe()
void Process( ThingToProcess1 concreteP ); // Called back from ThingToProcess1.ProcessMe
}
public interface IThingToProcess
{
void ProcessMe( IProcessor p );
}
public class ThingToProcess1 : IThingToProcess
{
public void ProcessMe( IProcessor p ) { p.Process( this ); }
}

Categories