C# 为基类方法创建的委托是否可以实际调用派生类方法?
我有以下代码:C# 为基类方法创建的委托是否可以实际调用派生类方法?,c#,delegates,C#,Delegates,我有以下代码: using System; using static System.Console; namespace Test { class Program { static void Main(string[] args) { Test.StartTest(); ReadLine(); } } public class Test {
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");
}
}
}
使用系统;
使用静态系统控制台;
名称空间测试
{
班级计划
{
静态void Main(字符串[]参数)
{
Test.StartTest();
ReadLine();
}
}
公开课考试
{
类SomeResult{}
类基类
{
公共虚拟TResult DoSomething()
{
WriteLine(nameof(BaseClass));
返回默认值;
}
}
类派生类:基类
{
公共覆盖TResult DoSomething()
{
WriteLine(名称(DerivedClass));
Func baseImplementation=base.DoSomething;
//这是有效的:return base.DoSomething();
返回baseImplementation();
}
}
公共静态无效开始测试()
{
DerivedClass实例=新的DerivedClass();
实例DoSomething();
//这是有效的:instance.DoSomething();
写线(“完成”);
}
}
}
基本上,我在类Test
中有BaseClass
和DerivedClass
(它源自BaseClass
),我认为前面的类在Test
中并不重要,但如果我遗漏了什么,我会像这样保留它)
BaseClass
具有虚拟方法DoSomething
,该方法DerivedClass
覆盖调用基类实现,但通过创建指向BaseClass.DoSomething
的Func
委托并调用该委托来实现(考虑到这只是一个简单的例子,并不是我在实际项目中想要完成的)
当运行程序时,会创建DerivedClass
的一个实例,并调用其DoSomething
方法,该方法应通过前面提到的委托调用BaseClass.DoSomething
。当我在Visual Studio中运行它时,它会按照我的预期工作,BaseClass.DoSomething
确实被调用(输出为“DerivedClass BaseClass Finished”)。但是,当在其他地方运行它时(Unity游戏引擎,但它不相关),代理不会调用BaseClass.DoSomething
,而是DerivedClass.DoSomething
(进入循环并导致堆栈溢出异常)。用注释掉的行不会发生这种情况//这是有效的:“,尽管我认为它们基本上是等价的
调用委托的预期行为不是总是执行
基类.DoSomething
,还是我遗漏了什么,这是一个实现细节,而不是语言中定义良好的规则?我的第一个假设是,这是Unity或它使用的Mono版本中的一个bug,但我不确定是否是还有一点我必须考虑。使用单C编译器6.12,我不能复制这个。@清扫器,我想你是指“意想不到的”行为。我认为我正在使用的Unity版本使用MUNO 5.11,虽然以前的统一版本中我不能复制这个问题,但似乎也使用了MON5.5.1mm,对我来说好像是个bug。