我有以下代码:
using System;
using static System.Console;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Test.StartTest();
ReadLine();
}
}
public class Test
{
class SomeResult {}
class BaseClass
{
public virtual TResult DoSomething<TResult>()
{
WriteLine(nameof(BaseClass));
return default;
}
}
class DerivedClass : BaseClass
{
public override TResult DoSomething<TResult>()
{
WriteLine(nameof(DerivedClass));
Func<TResult> baseImplementation = base.DoSomething<TResult>;
//This works: return base.DoSomething<TResult>();
return baseImplementation();
}
}
public static void StartTest()
{
DerivedClass instance = new DerivedClass();
instance.DoSomething<SomeResult>();
//This works: instance.DoSomething<int>();
WriteLine("Finished");
}
}
}
基本上,我在类Test
中有BaseClass
和DerivedClass
(它派生自BaseClass
((我认为前两个类在Test
中并不重要,但我会这样保留,以防我遗漏了什么(。
BaseClass
具有虚拟方法DoSomething
,DerivedClass
重写该方法以调用基类实现,但这样做是通过创建Func
委托";指向";到BaseClass.DoSomething
,并调用该委托(考虑到这只是一个简单的例子,而不是我在实际项目中试图完成的(。
运行程序时,会创建DerivedClass
的实例,并调用其DoSomething
方法,该方法应通过前面提到的委托调用BaseClass.DoSomething
。当我在Visual Studio中运行它时,它的工作方式正如我所期望的那样,BaseClass.DoSomething
确实被调用了(输出是"DerivedClass BaseClass Finished"(。然而,当在其他地方运行它时(Unity游戏引擎,但它不相关(,委托不会调用BaseClass.DoSomething
,而是调用DerivedClass.DoSomething
(进入循环并导致堆栈溢出异常(。这不会发生在用"//这起作用:";,尽管我认为它们基本上是等价的。
预期的行为不是调用委托总是执行BaseClass.DoSomething
吗?还是我遗漏了一些东西,这是一个实现细节,而不是语言中定义良好的规则我的第一个假设是,这是Unity或它使用的Mono版本中的一个bug,但我不确定是否还有其他问题需要考虑。
行为必须是委托执行基类方法,而不是派生类方法。我收到了Unity的确认,向后的行为确实是一个错误。