【问题标题】:Generic type parameter and Nullable method overload泛型类型参数和 Nullable 方法重载
【发布时间】:2023-03-31 21:05:01
【问题描述】:


我使用通用和可为空的代码:

// The first one is for class
public static TResult With<TInput, TResult>(this TInput o, 
          Func<TInput, TResult> evaluator)
    where TResult : class
    where TInput : class

// The second one is for struct (Nullable)
public static TResult With<TInput, TResult>(this Nullable<TInput> o, 
          Func<TInput, TResult> evaluator)
    where TResult : class
    where TInput : struct

请注意 TInput 约束,一个是类,另一个是结构。然后我将它们用于:

string s;
int? i;

// ...

s.With(o => "");
i.With(o => ""); // Ambiguos method

它会导致 Ambiguos 错误。但我还有另一对:

public static TResult Return<TInput, TResult>(this TInput o,
          Func<TInput, TResult> evaluator, TResult failureValue)
    where TInput : class

public static TResult Return<TInput, TResult>(this Nullable<TInput> o,
          Func<TInput, TResult> evaluator, TResult failureValue)
    where TInput : struct

这个编译成功

string s;
int? i;

// ...

s.Return(o => 1, 0);
i.Return(o => i + 1, 0);

我不知道为什么会发生这种情况。第一个看起来不错,但编译错误。如果第一个是,第二个('Return')应该是错误,但编译成功。我错过了什么吗?

【问题讨论】:

  • 作为一种风格注释,我会避免对 lambda 参数使用与已经在范围内的变量相同的名称。
  • 啊对,这实际上会导致编译错误。我只是匆忙粘贴和编辑代码。

标签: c# .net generics types nullable


【解决方案1】:

选择重载时不考虑泛型方法中的约束 - 在选择重载后检查它们。

参数类型内的约束被检查作为选择重载的一部分。这有点令人困惑,但最终还是有意义的。

我对此有一个blog post,这可能有助于进一步理解它。

另外请注意,您的第二个示例具有有助于类型推断的附加参数,这就是两者之间的区别。 TResult 被推断为 int,这会阻止第一个重载有效 - 没有从 (int? x) =&gt; x + 1Func&lt;int?, int&gt; 的转换,而 (int x) =&gt; x + 1 到 @987654327 的转换@。

【讨论】:

  • 我现在很困惑,我正在努力理解你的最后一段。两个 Func 代表根本不使用可为空的(int?)。只有第一个参数是。
  • @Hendry:每种情况下的第一个重载都会处理TInput = int?,因为您在int? 上调用它。因此,evaluator 参数类型将是 Func&lt;int?, TResult&gt;
  • 哦,我明白了,这就是为什么基于 lambda 函数的重载解析在第一个“返回”时失败并流向第二个的原因。非常感谢。
  • @JonSkeet 请考虑更新链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
相关资源
最近更新 更多