开发者

c# Generics problem

开发者 https://www.devze.com 2023-01-03 04:16 出处:网络
Can anyone tell me why this does not work?I would have thought the constraint开发者_运维技巧 would make it valid.

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; 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号