Question

Assume we have some classes

class Class1{ }
class Class2{ }
class Class3{ }

and I have a Type variable

Type t = /*some type unknown at compile-time*/;

variable t is Class1 or Class2 or Class3. I want to create an instance of that class. As I know I can use the following statement:

object instance = Activator.CreateInstance(t);

But I receive an object. And the question is: how do I cast this object to type that is in variable t. Or maby someone can suggest a workaround. Thanks

Was it helpful?

Solution

Unless there is some common base-class or interface that all 3 share, you can't - all you can call it is "object". Consider having them all implement an interface, and cast to that.

OTHER TIPS

If you want to avoid reflection, then

public interface IClass { }
class Class1 : IClass { }
class Class2 : IClass { }
class Class3 : IClass { }

IClass instance = (IClass)Activator.CreateInstance(t);

You could use the dynamic keyword:

dynamic instance = Activator.CreateInstance(t);

This works like if you're using object, but in this case the type is known only at runtime, so until you didn't run your program it supports everything. It is very common when dealing with Reflection.

For more info look here.

You has been told that you can't, and yet, you can.

First let's look you code:

class Class1{ }
class Class2{ }
class Class3{ }

void Main()
{
    Type t = /*some type unknown at compile-time*/;
    object instance = Activator.CreateInstance(t);
}

And your question:

how do I cast this object to type that is in variable t.

Well, if I only look to this information then the answer is: you can't, because there is an infinite set of types that may be in the variable t, in fact, some of them may have been defined after this code was writen (they didn't exist yet).

Well - as it seems to be - there is some other information:

variable t is Class1 or Class2 or Class3

Meaning that you have a finite set of possible types that may be in the variable t.

With that in mind you can just check them, for example:

class Class1{ }
class Class2{ }
class Class3{ }

void Main()
{
    var possibleTypes = new Type[]
    {
        typeof(Class1),
        typeof(Class2),
        typeof(Class3)
    };
    Type t = possibleTypes[(new Random()).Next(possibleTypes.Length)];
    object instance = Activator.CreateInstance(t);
    if (t.Equals(typeof(Class1)))
    {
        DoSomethingWithClass1(instance as Class1);
    }
    else if (t.Equals(typeof(Class2)))
    {
        DoSomethingWithClass2(instance as Class2);
    }
    else if (t.Equals(typeof(Class3)))
    {
        DoSomethingWithClass3(instance as Class3);
    }
}

void DoSomethingWithClass1(Class1 instance)
{
    //...
}

void DoSomethingWithClass2(Class2 instance)
{
    //...
}

void DoSomethingWithClass3(Class3 instance)
{
    //...
}

Well it works, and inside the methods for each class you can use whatever it is appropiate for that class.

"It is not very generic" - you say - "I don't want to write a new method each time a new class comes along!". And I Agree, you could solve that going into the depts of Reflection. But, honestly, it is pointless. As you have already been told there is nothing in common in those classes, so you are better of creating an interface to avoid Reflection.

Also, what was that you want to do with that object? Chances are you can find methods common to all the classes and use those in your new interface that the related class will implement from now onwards.

Ok, I know that at the time of writing there is already an accepted answer, still, I wanted to point out: Yes you can. (Everytime I find somebody who says you can't do something, I love to doble check :P).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top