为基本 class 方法创建的委托实际上可以调用派生的 class 方法吗?
Can a delegate created for a base class method actually call a derived class method?
我有以下代码:
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");
}
}
}
基本上,我在 class Test
中有 BaseClass
和 DerivedClass
(派生自 BaseClass
)(我认为这不重要前 classes 在 Test
中,但我会保留它以防遗漏某些东西)。
BaseClass
有虚方法 DoSomething
,DerivedClass
重写以调用基础 class 实现,但是通过创建 Func
委托来实现“指向”BaseClass.DoSomething
,并调用该委托(考虑到这只是一个准系统示例,而不是我在真实项目中试图完成的)。
当 运行 程序创建一个 DerivedClass
的实例,并调用它的 DoSomething
方法时,它应该像前面提到的那样通过委托调用 BaseClass.DoSomething
.当我 运行 它在 Visual Studio 中时,它按我预期的方式工作,BaseClass.DoSomething
确实被调用(输出是“DerivedClass BaseClass Finished”)。然而,当运行在其他地方(Unity游戏引擎,但它不相关)委托不调用BaseClass.DoSomething
,而是DerivedClass.DoSomething
(进入循环并导致堆栈溢出异常) .用“//This works:”注释掉的行不会发生这种情况,尽管我认为它们大部分是等价的。
预期的行为不会是调用委托总是执行 BaseClass.DoSomething
,还是我遗漏了什么,这是一个实现细节,而不是语言中定义明确的规则? 我的第一个假设是它是 Unity 或其使用的 Mono 版本中的错误,但我不确定是否还有其他需要考虑的问题。
行为必须是委托执行基本 class 方法,而不是派生的 class 方法。我收到 Unity 的确认,向后的行为确实是一个错误。
我有以下代码:
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");
}
}
}
基本上,我在 class Test
中有 BaseClass
和 DerivedClass
(派生自 BaseClass
)(我认为这不重要前 classes 在 Test
中,但我会保留它以防遗漏某些东西)。
BaseClass
有虚方法 DoSomething
,DerivedClass
重写以调用基础 class 实现,但是通过创建 Func
委托来实现“指向”BaseClass.DoSomething
,并调用该委托(考虑到这只是一个准系统示例,而不是我在真实项目中试图完成的)。
当 运行 程序创建一个 DerivedClass
的实例,并调用它的 DoSomething
方法时,它应该像前面提到的那样通过委托调用 BaseClass.DoSomething
.当我 运行 它在 Visual Studio 中时,它按我预期的方式工作,BaseClass.DoSomething
确实被调用(输出是“DerivedClass BaseClass Finished”)。然而,当运行在其他地方(Unity游戏引擎,但它不相关)委托不调用BaseClass.DoSomething
,而是DerivedClass.DoSomething
(进入循环并导致堆栈溢出异常) .用“//This works:”注释掉的行不会发生这种情况,尽管我认为它们大部分是等价的。
预期的行为不会是调用委托总是执行 BaseClass.DoSomething
,还是我遗漏了什么,这是一个实现细节,而不是语言中定义明确的规则? 我的第一个假设是它是 Unity 或其使用的 Mono 版本中的错误,但我不确定是否还有其他需要考虑的问题。
行为必须是委托执行基本 class 方法,而不是派生的 class 方法。我收到 Unity 的确认,向后的行为确实是一个错误。