Question

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 ?

Was it helpful?

Solution

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.

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