tags:

views:

103

answers:

3

I have 2 base classes FirstBase and SecondBase. I also have 2 class derive from them, DerivedFirst and DerivedSecode and both of them has almost of same property. Source code is like below.

public abstract class FirstBase
{
    //some method
}

public abstract class SecondBase
{
    //some method
}

public class DerivedFirst : FirstBase
{
    //override methods of its parent

    public static implicit operator DerivedFirst(DerivedSecond second)
    {
        //doing some logic here
    }
}

public class DerivedSecond : SecondBase
{
    //override methods of its parent

    public static implicit operator DerivedSecond(DerivedFirst first)
    {
        //doing some logic here
    }
}

From this code I can create instance of DerivedFirst and assign to DerivedSecond without any problem. However when I try to convert list of them like code below, It has no result.

List<DerivedFirst> firstList;
List<DerivedSecond> secondList;

//doing some operation here

List<DerivedSecod> test = firstList.Cast<DerivedSecond>(); // don't have any output here.

How can I convert firstList to List()?

+4  A: 

User-defined implicit conversions are considered only at compile time, not at run-time (source). You can use Select instead:

List<DerivedSecond> foo = firstList.Select(x => (DerivedSecond)x).ToList();
Mark Byers
I already try this method, but when I debug into foo is show 'System.InvalidCastException' {"Unable to cast object of type 'DerivedFirst' to type 'DerivedSecond'."}
In The Pink
@Ekkapop: I have updated my answer.
Mark Byers
+2  A: 

Your desired behavior does not work. The static implicit operator is nothing more than a fancy way to write code. DerivedFirst cannot really be casted into a DerivedSecond.

The call of FirstList.Cast<DerivedSecond> works since LINQ streams over the input list while accessing its items. As soon as you access any item in the resulting IEnumerable&ltDerivedSecond> you get an InvalidCastException.

Try this Visual Studio Test code to see what I mean:

   [TestClass]
   public class UnitTest1 {
      class DerivedA {
         public static implicit operator DerivedA(DerivedB b) {
            return new DerivedA();
         }
      }
      class DerivedB {
         public static implicit operator DerivedB(DerivedA a) {
            return new DerivedB();
         }
      }

      [TestMethod]
      public void TestMethod1() {
         IList<DerivedA> lista = new List<DerivedA> {
            new DerivedA()
         };
         var casted = lista.Cast<DerivedB>();

         try {
            DerivedB b = casted.First();
            Assert.Fail();
         } catch (InvalidCastException) {
            // exception will be thrown
         }
      }
   }

Edit: The only solution to "cast" the objects is to use the "Select" method:

var casted = lista.Select(a => (DerivedB)a);

Greets Flo

Florian Reischl
A: 

You have just talked about Variance. C# actually introduces Co-variance in .NET 4.0. So if you are in C# 4.0, you can easily do this using out operator in your list.

Check my article

http://www.abhisheksur.com/2010/06/c-40-features.html

I hope this would help you.

Otherwise you can use Loop to cast each individual objects to create a separate list of that type.

abhishek