繁体   English   中英

为什么编译器选择了错误的方法重载?

[英]Why is the compiler choosing the wrong method overload?

我有这个简单的方法:

public void CacheDelegate(Object obj, MemberInfo memberInfo)
{
   switch (memberInfo.MemberType)
   {
    case MemberTypes.Field:
       var fieldInfo = (FieldInfo) memberInfo;
       CacheDelegate(obj, fieldInfo);
       break;
    case MemberTypes.Property:
       var propertyInfo = (PropertyInfo) memberInfo;
       CacheDelegate(obj, propertyInfo);
       break;
    case MemberTypes.Method:
       var methodInfo = (MethodInfo) memberInfo;
       CacheDelegate(obj, methodInfo);
       break;
    default:
       throw new Exception("Cannot create a delegate for MemberInfo provided.");
    }
}

上面的方法解析memberInfo的类型,并从以下方法调用适用的方法:

public void CacheDelegate(Object obj, FieldInfo fieldInfo)
{
   // Do stuff...
}

public void CacheDelegate(Object obj, PropertyInfo propertyInfo)
{
   // Do stuff...
}

public sealed override void CacheDelegate(Object obj, MethodInfo methodInfo)
{
   // Do stuff...
}

问题在于最后一个案例标签case MemberTypes.Method不会通过Method Info重载调用CacheDelegate方法,而是通过Member Info重载来调用CacheDelegate! 因此,它基本上只是一次又一次地递归调用自己。 我尝试在调用方法时指定参数名称methodInfo:methodInfo,但是Unity引擎告诉我最好的重载方法不包含名为methodInfo的参数。

我完全不知道为什么会这样。 任何帮助将不胜感激。

重载解析的工作方式如下。

从调用的类型开始,找到可以使用的在该类型上声明的方法集。

如果该集合为空,则尝试对声明的基本类型或接口进行相同的操作。 继续向上移动层次结构,直到找到至少一种匹配的方法,否则将出错。

在找到的集合中,使用最特定的方法。 如果是平局则出错。

因此,在这四个方法中,有三个在此类中声明。 这三个中的两个不适用。 显然public void CacheDelegate(Object obj, MemberInfo memberInfo)只有public void CacheDelegate(Object obj, MemberInfo memberInfo)作为正确的正确类来调用,因此可以调用它。

您可以使用((BaseType)this).CacheDelegate(obj, methodInfo); 强制您要进行的呼叫,因为基本类型只有一个CacheDelegate重载可供选择。

乔恩·汉纳(Jon Hanna)已经解释了为什么会发生这种情况,我将通过提供可阅读详细信息的源规范进行补充: https : //msdn.microsoft.com/zh-cn/library/aa691336(v=vs.71 )的.aspx

您可以通过以下几种方式解决问题:

  • 不要覆盖或重载该方法,请使用其他名称。
  • 不要重写该方法,使用不同的参数进行重载,例如添加object ignoreMe 这将迫使重载兼容,但是大多数人都认为它远非优雅。
  • 而不是覆盖,而是使用new隐藏方法。 我不确定100%涉及方法隐藏时重载解析的工作原理,但导致它使用正确的方法。 请记住,这样做当然会消除它的多态性。
  • 使用反射手动找到正确的重载,然后调用它。 这是最乱的,而且开销最大。 根据您的具体情况,这可能是问题,也可能不是问题。 但是,如果您确实想使用该确切的覆盖/重载组合,则它是保留完整多态性的唯一解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM