C#通用约束中的通配符

时间:2011-12-08 07:00:32

标签: c# .net generics covariance generic-constraints

我知道C#没有通用的通配符,并且泛型方法可以实现类似的效果,但我需要在字段中使用通配符,如果有任何方法可以解决编码。

List<State<Thing>> list;

void AddToList<T>() where T : Thing {
    list.Add(new State<T>());
}

当然,这不起作用,因为添加的对象不是State<Thing>类型,而是State<T> where T : Thing类型。是否可以将列表的最内部类型调整为Java等效于? extends Thing而不仅仅是Thing

3 个答案:

答案 0 :(得分:4)

请注意,C#4确实有额外的差异支持,但由于各种原因(包含“in”和“out”方法,并且是一个类),它不适用于List<T>情况。

但是,我认为解决这个问题的方法是:

interface IState { // non-generic
    object Value { get; } // or whatever `State<Thing>` needs
}
class State<T> : IState {
    public T Value { get { ...} } // or whatever
    object IState.Value { get { return Value; } }
}

List<IState> list; ...

然后允许您添加任何State<T>。它并没有真正使用T的大部分内容,并且需要使用强制转换才能从object转到T,但......它至少会起作用。

答案 1 :(得分:3)

您可以尝试这样的事情:

    interface IState<out T> { }
    class State<T> : IState<T> { }
    class Thing {}

    List<IState<Thing>> list;

    void AddToList<T>() where T : Thing
    {
        list.Add(new State<T>());
    }

答案 2 :(得分:0)

按以下方式声明您的列表:

class State<T> where T : Thing
{
    ...

    List<State<T>> list = new List<State<T>>();
    // or
    public class StateList<T> : List<State<T>>
    {
         void AddToList(T item);
    }
}

然后编译器就能转换。