Reputation: 9648
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()?
Upvotes: 4
Views: 196
Reputation: 3866
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<DerivedSecond>
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);
Upvotes: 2
Reputation: 2992
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.
Upvotes: 0
Reputation: 838376
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();
Upvotes: 4