【问题标题】:functional Option type in c# not support invariantc#中的功能选项类型不支持不变量
【发布时间】:2016-05-11 15:19:09
【问题描述】:

这样的界面蓝图:

   public interface IOption<out T>{
      IOption<R> Map<R> (Func<T, R> func);
      IOption<R> FlatMap<R> (Func<T, IOption<R>> func);
      T Get ();
      bool IsEmpty ();
      Y GetOrElse (Func<Y> defaultValue) where Y: T;//error
    }

重要的是它应该支持变体。我坚持Y GetOrElse (Func&lt;Y&gt; defaultValue) where Y: T;

错误显示The covariant type parameter T must be contravariantly valid on IOption&lt;T&gt;.GetOrElse(Func&lt;T&gt;)

此外,Func 应该定义为 public delegate R Func&lt;in A, out R&gt;(A a); .NET2.0 而不是将 varient 附加到 Func 泛型类型。

感谢任何建议。

更新
来自Scala 语言的选项设计。我知道Y 应该是T 的超类型,但它似乎无法简单地定义where T: Y,我该怎么办?

我还有一个问题——为什么不能直接定义T GetOrElse&lt;T&gt; (T defaultValue);???

【问题讨论】:

  • 你的接口在结果类型中已经是协变的,所以你可以定义T GetOrElse(Func&lt;T&gt; defaultValue)
  • @Lee,编译器会打印一个错误,因为Func 的 T 不能作为协变量。它定义为delegate T Func&lt;out T&gt;()

标签: c# optional


【解决方案1】:

C# 不支持 scala 等泛型参数的下限,但您可以将 GetOrElse 设为扩展方法以利用 IOption&lt;T&gt; 接口的协方差:

public static T GetOrElse<T>(this IOption<T> opt, Func<T> defaultValue)
{
    return opt.IsEmpty() ? defaultValue() : opt.Get();
}

然后您可以在呼叫站点指定您想要的类型,例如:

IOption<Dog> do = ...;
var ao = o.GetOrElse<Animal>(() => new Cat());

【讨论】:

  • 出现新错误:error CS1106: IOptionEx.GetOrElse&lt;T&gt;(this IOption&lt;T&gt;, Func&lt;T&gt;): Extension methods must be defined in a non-generic static class
  • 对不起,我忘了static 用于扩展类
猜你喜欢
  • 2021-04-20
  • 1970-01-01
  • 2019-09-04
  • 2014-07-23
  • 2017-01-24
  • 1970-01-01
  • 2013-10-12
  • 2011-02-20
  • 1970-01-01
相关资源
最近更新 更多