【问题标题】:covariance with struct constraint与结构约束的协方差
【发布时间】:2018-04-27 01:03:05
【问题描述】:

我想知道为什么这样的事情毕竟是允许的?

interface IProducer<out T> where T : struct

如果 struct 是值类型,则协方差不起作用,因为 struct 是值类型。我在这里想念什么?

【问题讨论】:

  • 可以考虑Vacuously true。请记住,编译器的目的是生成有用的程序——而不是纯粹的数学程序——因此有时它可能允许你做出包含冗余或废话的“陈述”。
  • "out T" 在这种情况下会阻止在该接口上声明某些成员(如void Set(T value);),所以你不能说它完全没用或没有效果。
  • 是有道理的,所以它的两个独立的规则相互不依赖,但是这两个规则相交在定义上产生了自相矛盾。感谢您的回答,如果您可以将其作为答案,我会接受。

标签: c# struct covariance value-type


【解决方案1】:

如果您查看 MSDN 中的 Generic out modifier,则声明声明的类型化参数必须满足两个条件:

  • 类型参数仅用作接口方法的返回类型,不用作方法参数的类型。
  • 类型参数不用作接口方法的通用约束。

在代码方面,这里是不同的:

interface ITest<out T1, T2>  
{
    T1 GetValue();
    T2 GetValue2();
    void SetValue(T1 Arg1); //Compile Error, Condition 1
    void SetValue(T2 Arg1);
    void SetValue2<T3>(int Arg) where T3 : T1; //Compile Error, Condition 2
    void SetValue<T3>(int Arg) where T3 : T2;
}

因此,您的 T1 不能用作方法的输入参数,也不能用作另一个通用约束。

由于您有一个约束条件,说明 T 必须是一个结构,因此条件 2 自动满足。

所以这两条语句相加意味着:

只能用作返回值 (out) 的结构 (where T: struct)。

【讨论】:

    【解决方案2】:

    如果你声明接口

    interface IProducer<out T> where T : struct
    

    那么你是对的,你不能使用协方差,因为它不适用于结构,但这仍然是允许的,因为协方差不是 out 修饰符的唯一效果。

    它还限制使用泛型类型返回类型,因此这意味着您将无法将这样的成员添加到您的接口中

    void MyMethod(T t);
    

    这可能不是很有用,但有人可以使用它来强制执行此规则,因此语言没有理由不支持这一点。

    【讨论】:

      猜你喜欢
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 2018-08-22
      • 2017-01-10
      相关资源
      最近更新 更多