A sample code I tried to return an instance of class is given below.
public object getConstructorclass(int i)
{
if(i==1)
{
Type type = Type.GetType("test1");
}else
{
Type type = Type.GetType("test2");
}
return Activator.CreateInstance(type);
}
var objcls = getConstructorclass(1);
objcls.callclass();//error occured
How can I mention the class type here since the type is not known at compile time but it will decided at runtime.In the above example i just pass a value 1 (it can be anything and that class will be called accordingly), and the class test1 called.
here I will get an error on the line objcls.callclass()
, because objcls
is an object
instance that doesn't have a callclass()
method.
How can I restructure this piece of code? My aim is if I mention a class in the getConstructorclass()
method, an object should be returned so as to use it in the further code to invoke the members of that class.
If you know that your classes will have this method, you should use a common interface for them and implement it accordingly. Then you will work with classes that you have made sure it will work.
It would look like this
I don't think you should use some generic object returning constructor based on an int variable, if your classes don't have anything in common. It's really weird to handle it like this and it may lead to various problems (some of which you're currently already experiencing). Generic class constructors make sense if the classes are somewhat related and you can predict the outcome, but to create a do-it-all method.. Not so sure about correctness of such approach.
Anyway, if you insist (not recommended, but as you wish), you can create some checks for a type like this:
But it gets very error prone soon, refactoring will probably be a nightmare etc., but it's your call..
Or you maybe can use solution from pwas, but to me it seems unnecessarily complicated for such a basic task. Looks nice and all, but it still returns only the type "object", so it doesn't really solve your specific problem.
Also, to address one issue I'm not sure you understand - you've already created the instance, you just return type object. That is why you can't call any specific methods on this object, because first you have to cast it to something, that actually has that method and make sure the cast can be done (inheritance etc).
Declare your variable as dynamic
Using this the will be determined at run-time, whatever the
getconstrorclass
method returns. You can access any member of the type and you won't get any error at compile-time. But if you try to access a member which doesn't exists you will get aRuntimeBinderException
at runtime.not sure what you want to achieve in the end, but this looks like a job for "Dependency Injection" - here is a nice sample using autofac
If
interface
solution (see other answers) is enough, don't look at this answer. When you can't use common base class / interface and you still want call members, you can use solution withis
keyword (and check types). Instead of writing many ifs for each case, you can use fluent API:Solution:
Remeber - it would be more elegant to use common interface (as other answers say) - my is only alternative way.
I would recommend using an
interface
and restricting the classes that you can instantiate this way to only those that implement the interface.