0

我正在四处寻找关于泛型我能做什么和不能做什么。我有这种情况,就我而言,编译器应该抛出关于模棱两可的方法调用的错误,但它编译得很好。这是为什么?

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;
    }
}
4

4 回答 4

4

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

Strategy(int i)

和一个

Strategy(params object[] parameters)这是继承自FunctionStrategyBase

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

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

于 2014-03-19T21:15:04.207 回答
2

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

7.4.3.2更好的函数成员 给定一个带有一组参数表达式 { E1, E2, ..., EN } 的参数列表 A 和两个具有参数类型 { P1, P2, ..., PN } 的适用函数成员 MP 和 MQ和 { Q1, Q2, ..., QN },MP 被定义为比 MQ 更好的函数成员,如果

...

• 否则,如果 MP 以其正常形式适用且 MQ 有一个 params 数组且仅适用于其扩展形式,则 MP 优于 MQ。

• 否则,如果 MP 的声明参数比 MQ 少,则 MP 优于 MQ。如果这两种方法都具有参数数组并且仅适用于它们的扩展形式,则可能会发生这种情况。

于 2014-03-19T21:31:31.913 回答
1

您的代码仅显示一个方法调用,这是使用反射完成的。

因此,无法在编译时完成解析,这就是您的代码编译得很好的原因。

此外,没有歧义,因为每个类只有一个方法。

于 2014-03-19T21:07:07.953 回答
0

如果我正确解释此评论

策略,两种策略的签名不同,如何区分 param object[] 参数和 int i?

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

于 2014-03-19T21:10:35.253 回答