为什么这不会抛出关于歧义方法的某种错误呢?

本文关键字:方法 错误 歧义 出关 于歧义 为什么 | 更新日期: 2023-09-27 17:50:57

我想看看在泛型方面我能做什么,不能做什么。我有这种情况,就我而言,编译器应该抛出一个错误,关于模棱两可的方法调用,但它编译得很好。为什么呢?

public interface IFunctionStrategy<T>
{
    T Strategy(params object[] parameters);
}
public class FunctionStrategyBase<T> : IFunctionStrategy<T>
{
    public virtual T Strategy(params object[] parameters)
    {
        MethodBase current = MethodBase.GetCurrentMethod();
        return (T)GetType().InvokeMember(current.Name, BindingFlags.InvokeMethod | BindingFlags.Public, Type.DefaultBinder, this, parameters);
    }
}
public class ConnectionConnect : FunctionStrategyBase<int>
{
    public int Strategy(int i)
    {
        return i;
    }
}

为什么这不会抛出关于歧义方法的某种错误呢?

没有歧义。正如你自己在评论里说的,签名是不一样的。在ConnectionConnect的上下文中,现在有一个

Strategy(int i)

继承自FunctionStrategyBaseStrategy(params object[] parameters)

是完全可以接受的重载。不管在运行时发生了什么,如果你不知道这些函数的机制,可能会发生奇怪的行为,编译器认为这没有严格的问题。

在运行时调用时,程序将使用最接近匹配签名的,然后检查可以对其进行有效隐式强制转换的签名。如果你传递一个int给Strategy, Strategy(int i)方法将被使用。如果没有,它会隐式地将int框起来并将其传递给Strategy(params object[] parameters),这是该语言的一个特性。

它在c#规范中定义了如何解析方法,因此没有歧义:

7.4.3.2更好的函数成员给定一个实参列表A,其中包含一组实参表达式{E1, E2,…、EN}和两种适用功能成员MP和MQ的参数类型为{P1, P2,…, PN}和{Q1,Q2,……,如果

,则MP被定义为比MQ更好的函数成员

•如果正常形式的MP适用,且MQ具有params数组并且只适用于其展开形式,则MP是

•否则,如果MP声明的参数比MQ少,则MP是比MQ好。如果两个方法都有参数数组和

你的代码只显示了一个方法调用,它是通过反射完成的。

因此,解析不能在编译时完成,这就是为什么你的代码编译得很好。

而且,没有歧义,因为每个类只有一个方法。

如果我理解正确

策略,两种策略在签名上不同,会怎样呢能够区分参数对象[]参数和int i?

param object[]int i不需要分开,因为param object[]指定了任何类型的可变数量的参数。因此,当声明int i时,i被装箱到object中,并作为单个元素数组传递给函数。但是不确定我是否正确地解释了注释