【问题标题】:Wildcards in C# generic constraintsC# 泛型约束中的通配符
【发布时间】:2011-12-08 07:00:31
【问题描述】:

我知道 C# 没有泛型通配符,通过泛型方法也可以达到类似的效果,但是我需要在字段中使用通配符,如果有什么办法可以解决编码。

List<State<Thing>> list;

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

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

【问题讨论】:

  • 你能把你的名单声明为List&lt;State&lt;T&gt;&gt; where T : Thing吗?
  • @abatishchev:也许把它作为答案发布?
  • @konrad: Done

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


【解决方案1】:

请注意,C# 4 确实有额外的变化支持,但它不适用于 List&lt;T&gt; 情况,原因有多种(同时具有“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; } }
}

List<IState> list; ...

其中然后允许您添加任何State&lt;T&gt;。它并没有真正使用很多T,并且需要一个演员才能从objectT,但是......它至少可以工作。

【讨论】:

  • 我真的不明白为什么我不能像下面这样:(State&lt;Thing&gt;)new State&lt;T&gt;T : Thing!不过可以(Thing)new 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; 有一个演员表。
【解决方案2】:

你可以试试这样的:

    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>());
    }

【讨论】:

  • 我更喜欢这个,但我不能使用 C# 4。
【解决方案3】:

如下声明您的列表:

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);
    }
}

然后编译器就可以转换了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多