0

See the following sample code.

public interface I
{
    int ID { get; set; }
}

public class B : I
{
    public int ID { get; set; }
    public string PropB { get; set; }
}

public class A : B
{
    public string PropA { get; set; }

    public IEnumerable<I> GetListOfBase()
    {
        // Attempt #1
        var list1 = new List<I>();
        B b1 = this as B;
        list1.Add(b1);

        // Attempt #2
        var list2 = new List<I>();
        B b2 = (B)this.MemberwiseClone();
        list2.Add(b2);


        return list1;
    }
}

private static void TestGetListOfBase()
{
    var a = new A() { ID = 1, PropA = "aaa", PropB = "bbb" };
    var list = a.GetListOfBase();
}

In both my attempts, the list contains instances of A. I need it to contain instances of B. I am trying to avoid creating a new B, then copying the properties of A to B (I assume that will work!).

EDIT: the reason I need a list of Bs is that later on each B is passed into NPoco (a .NET micro ORM, derived from PetaPoco). NPoco takes the name of the type and uses it to determine the DB table to map to. Therefore it is critically important that a variable of the correct type is passed to the method.

Laurence
  • 980
  • 12
  • 31
  • Possible duplicate of [Convert List to List](http://stackoverflow.com/questions/1817300/convert-listderivedclass-to-listbaseclass) – Bassem Apr 06 '16 at 22:12
  • 1
    Since A is derived from B, any instane of A is an instance of B. Anywhere you can use a B, you can use an A as well. Can you clarify why you need to create a list of B's? – oɔɯǝɹ Apr 06 '16 at 22:13
  • It is so I can pass the list into NPoco (a .NET micro ORM, derived from PetaPoco). NPoco takes the name of the type and uses it to determine the DB table to map to. Therefore it is critically important that a variable of the correct type is passed to the method. – Laurence Apr 06 '16 at 22:17
  • In that case you will need to create new instances as B and copy the values from the instances of A. You cannot 'fake' the type of a class. Using a 'copy constructor' may help here. Are you sure that you want to leave out all the values of A when persisting the data? – oɔɯǝɹ Apr 06 '16 at 22:19

2 Answers2

1

No, there is no way to "convert" instance of derived class to instance of base class. You have to create new instances of base class and copy properties.

There are multiple ways of doing so including manually copy each property (works for small number of properties). This operation frequently it is called "mapping" (hopefully it will help with your search for tools).

Note if you are fine with just having different type for list Enumerable.OfType<T>() or Enumerable.Cast<T>() followed by ToList() would solve it in single statement.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • The list must be List where I is the interface. I guess I will have to use a mapping technique. – Laurence Apr 06 '16 at 22:23
  • @Laurence Is your actual goal to hide A from callers? Proxy `ProxyI` that implements all methods of interface `I` by forwarding to actual `A` object `innerA` could be better option. – Alexei Levenkov Apr 06 '16 at 22:30
  • (Missed comment on post - clearly proxy is wrong approach in case exact type is required). – Alexei Levenkov Apr 06 '16 at 22:31
0

You can use a copy constructor to easily create instances of type B given an instance of type A (or anything that is assignable to B):

public class B : I
{
    public int ID { get; set; }
    public string PropB { get; set; }

    public B(source B)
    {
        // copy values
        this.ID = source.ID;
        this.PropB = source.PropB;
    }
}

You can call it like this:

A instanceOfA = new A();
B instanceOfB = new B(instanceOfA);
// typeof(instanceOfB) == B
oɔɯǝɹ
  • 7,219
  • 7
  • 58
  • 69