c# - 除非显式设置泛型类型,否则不会调用 Nullable<T> 上的扩展方法

标签 c# extension-methods

在调查另一个问题:“Why there is no Nullable<T>.Equals(T value) method? ”时,我在 Nullable<T> 上做了一个扩展方法暴露了一个通用的 Equals<T>(T)方法:

public static class NullableExtensions
{
    public static bool Equals<T>(this T? left, T right) where T : struct, IEquatable<T>
    {
        if (!left.HasValue)
            return false;

        return right.Equals(left.Value);
    }
}

然而,这样调用它:

double? d = null;
d.Equals(0.0);

调用基地 Equals(object)装箱,正如您在 IL 中看到的那样:

IL_0000: nop
IL_0001: ldloca.s d
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<float64>
IL_0009: ldloca.s d
IL_000b: ldc.r8 0.0
IL_0014: box [mscorlib]System.Double
IL_0019: constrained. valuetype [mscorlib]System.Nullable`1<float64>
IL_001f: callvirt instance bool [mscorlib]System.Object::Equals(object)

如果我将调用更改为显式声明泛型类型:

d.Equals<double>(0.0);

它调用我的扩展方法:

IL_0000: nop
IL_0001: ldloca.s d
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<float64>
IL_0009: ldloc.0
IL_000a: ldc.r8 0.0
IL_0013: call bool ConsoleApplication8.NullableExtensions::Equals<float64>(valuetype [mscorlib]System.Nullable`1<!!0>, !!0)

为什么编译器不选择扩展方法而不是 Equals(object)方法?

是不是因为我刚刚选择了一个糟糕的方法名称 Equals<T>(T)它实际上不是 Equals 的真正覆盖而不是继承查找的一部分?

最佳答案

Why does the compiler not choose the extension method over the Equals(object) method?

如果没有其他选择,考虑扩展方法。这是一个回退——它不是实例方法的正常重载决策的一部分。这并非特定于可空类型 - 它是正常扩展方法调用的一部分。

来自规范的第 7.6.5.2 节:

In a method invocation of one of the forms

[...]

if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation.

(强调我的。)

关于c# - 除非显式设置泛型类型,否则不会调用 Nullable<T> 上的扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18736146/

相关文章:

c# - 我可以有一个 DataGridView 单元格,我可以在其中键入内容或从下拉列表中进行选择吗?

c# - 实例化并初始化多维数组 C#

java - Java AES/CBC/PKCS5Padding 的 C# 加密/解密

c# - 如何为 ICollection<T> 定义扩展方法,其中 T : IMyInterface without Specifying T in the Method Definition

c# - 使用这种(基于扩展方法的)速记的可能陷阱

c# - DispatcherTimer WPF 异步

c# - Azure Active Directory 不会使用 ASP.NET Core 2.1 MVC 注销

c# - 您能否将扩展方法的范围限制为具有特定属性的类?

c# - 您见过的最好或最有趣的扩展方法用法是什么?

c# - 错误 : Extension methods must be defined in a top level static class (CS1109)