c# Generics problem
Can anyone tell me why this does not work? I would have thought the constraint开发者_运维技巧 would make it valid.
public class ClassA<T> where T : ICommon
{
public ClassA()
{
ClassB b = new ClassB();
IEnumerable<T> alist = new List<T>;
b.Items = alist;
//Error: cannot convert from IEnumerable<T> to IEnumerable<ICommon>'
}
}
public class ClassB
{
public IEnumerable<ICommon> Items { get; set;}
....
}
This will work in C# 4 with a tweak, but not in C# 3. What you're looking for is generic variance, which has been supported in the CLR since .NET 2.0, but not in C# until v4.
Even in C# 4, you need to also constrain T to be a reference type - as covariance doesn't work over value types. For example, List<int>
can't be converted to IEnumerable<IComparable>
even though int
implements IComparable
.
Having tweaked your code a bit (there were a few typos, effectively), this compiles with the C# 4 compiler:
using System.Collections.Generic;
public interface ICommon {}
// Note the "class" part of the constraint
public class ClassA<T> where T : class, ICommon
{
public ClassA()
{
ClassB b = new ClassB();
IEnumerable<T> alist = new List<T>();
b.Items = alist;
}
}
public class ClassB
{
public IEnumerable<ICommon> Items { get; set;}
}
If you're stuck in C# 3 and .NET 3.5, an alternative would be to use Cast<T>()
:
b.Items = alist.Cast<ICommon>();
This is called covariance (or contra? I'm not sure), and is working only in C# 4.0.
You cannot cast IEnumerable<Common>
to IEnumerable<ICommon>
. (when Common implements ICommon.)
Try using
b.items = from f in alist select (T)f;
精彩评论