Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic cast using Type of object C#

I have one abstract class named A, and other classes (B, C, D, E, ...) that implements A

I also have a list of A objects.
I'd like to be able to cast dynamicly each of the object in that list to their "base" type (ie B, C, D, ...) to be able to call their constructor in an other method.

Here is what I have done for now :

abstract class A { }
class B : A { }
class C : A { }
class D : A { }
class E : A { }
// ... 

class Program
{
    static void Main(string[] args)
    {
        List<A> list = new List<A> { new B(), new C(), new D(), new E() };
        // ...

        foreach (A item in list)
        {
            A obj  = foo(item);
        }
    }

    public static A foo(A obj)
    {
        if (obj.GetType() == typeof(B))
        {
            return bar((B)obj);
        }
        else if (obj.GetType() == typeof(C))
        {
            return bar((C)obj);
        }
        // ... same for D, E, ...
        return null;
    }

    public static T bar<T>(T obj) where T : class, new()
    {
        // To use the constructor, I can't have here an abstract class.
        T newObj = new T();
        return newObj;
    }

It works, but I'd like to find an other way but to test for each class that implements A if their type equals the type of my object, and cast it afterwards.

I have nearly 15 classes like B, C, D, ... and I might have more. In order to have something simple, clear and maintainable, I'd like to avoid this methods, and the 15+ "if(...) else(...)".

Do you see a way to do so ?

like image 217
Sharpac Avatar asked Jan 14 '13 15:01

Sharpac


1 Answers

Modify bar in this way:

public static T bar<T>(T obj) where T : class
{
    var type = obj.GetType();
    return Activator.CreateInstance(type) as T;
}

Then modify foo:

public static A foo(A obj)
{
    return bar(obj);
}

Note that I had to remove the new() constraint. That had to be done to avoid casting your obj inside of foo. You can check at runtime if the type has a parameterless constructor, though.

like image 189
Mir Avatar answered Sep 22 '22 03:09

Mir