C#通用约束中的通配符

zmt*_*thy 9 .net c# generics covariance generic-constraints

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

List<State<Thing>> list;

void AddToList<T>() where T : Thing {
    list.Add(new State<T>());
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ell 4

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

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

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; } }
}
Run Code Online (Sandbox Code Playgroud)

List<IState> list; ...
Run Code Online (Sandbox Code Playgroud)

然后您可以添加任何State<T>. 它并没有真正使用太多的T,并且需要从object到进行强制转换T,但是......它至少会起作用。

  • @abatishchev 因为“SomeSpecificThing”**是**“Thing”;但“State&lt;SomeSpecificThing&gt;”是“State&lt;Thing&gt;”这句话*不*正确。没有继承等。如果它是一个通用接口,如果 **可能** 可能是 `IState&lt;out Thing&gt;`,在这种情况下,4.0 方差规则开始应用,并且 **那么** 是的,有从“IState&lt;SomeSpecificThing&gt;”到“IState&lt;Thing&gt;”的强制转换。 (3认同)