c#不根据参数类型(继承)选择我想要的函数
我不确定如何解释这一点,所以我将展示我的示例并详细说明c#不根据参数类型(继承)选择我想要的函数,c#,inheritance,types,parameters,C#,Inheritance,Types,Parameters,我不确定如何解释这一点,所以我将展示我的示例并详细说明 using System; namespace Demo { static class Program { static void Main() { var test = new ExampleClass(new Bar()); Console.WriteLine(test); } } class Examp
using System;
namespace Demo
{
static class Program
{
static void Main()
{
var test = new ExampleClass(new Bar());
Console.WriteLine(test);
}
}
class ExampleClass {
public Foo _foo;
public ExampleClass(Bar bar)
{
_foo = bar;
}
public override String ToString() {
return print(_foo);
}
String print(Bar bar) {
return bar.Name;
}
String print(Foo foo) {
return foo.ToString();
}
}
class Bar : Foo
{
public String Name;
}
class Foo
{ }
}
好吧,这不起作用
虽然我可以在声明中看到\u foo
的类型是foo
,但它也可以是Bar
,因为它继承自foo
我的问题是:
为什么编译器看不到\u foo
的实际类型
如果类型是Foo
的派生类,为什么总是执行print(Foo)
已编辑
编辑了我的示例代码,因为它仍然包含在我的大部分原始代码中
感谢Anthony Pegram提供的示例。我尝试了这个方法,但是如果类SyntaxNode派生自类BaseClassExtension,那么它会像预期的那样工作-因此很难从您向我们展示的代码中看出问题所在 正如我所期望的那样:
using System;
namespace Demo
{
static class Program
{
static void Main()
{
var test = new myNode();
Console.WriteLine(test);
}
}
class myNode
{
public SyntaxNode originalNode = new SyntaxNode{Name = "SyntaxNode"};
public override string ToString()
{
return print(originalNode); // This calls print(BaseClassExtention Class)
}
string print(BaseClassExtention Class) // <= This gets called.
{
return Class.Name;
}
string print(BaseClass b)
{
return b.ToString();
}
}
class BaseClass
{}
class BaseClassExtention : BaseClass
{
public string Name { get; set; }
}
class SyntaxNode: BaseClassExtention
{
}
}
使用系统;
名称空间演示
{
静态类程序
{
静态void Main()
{
var test=newmynode();
控制台写入线(测试);
}
}
类myNode
{
public SyntaxNode originalNode=新的SyntaxNode{Name=“SyntaxNode”};
公共重写字符串ToString()
{
返回print(originalNode);//这调用print(baseclassextension类)
}
字符串打印(BaseClassExtension类)//您的代码并不能很好地说明您的问题,因为您引入了类型为SyntaxNode
的字段,但没有显示它与BaseClass/BaseClassExtension
类型层次结构的关系。但是,在给定可理解的类型时,仍然可以回答一些问题
我的问题是:.net运行时为什么看不到原始节点的实际类型?为什么它总是打印(BaseClass),即使类型是BaseClasseExtension
NET运行时不是决定使用哪个重载的对象。这是编译器的一个属性,它使用它所拥有的关于变量类型(或字段、属性)的信息来决定使用哪个重载
一个简单的演示。假设我们有
class Foo { }
class Bar : Foo { }
void Do(Foo foo)
{
Console.WriteLine("Foo overload");
}
void Do(Bar bar)
{
Console.WriteLine("Bar overload");
}
然后你就有了密码
Foo foo = new Bar();
Do(foo);
您有一个类型为Foo
的变量,它恰好引用了类型为Bar
的对象。编译器在编译时发出代码来调用Foo
重载,因为它知道这一点,坦白说,这就是您告诉它要做的。(事实上,我们将它实例化到前面的一行中的类型<代码> Bar <代码>中并不是特别相关的。在下一行中,只需考虑<代码> FoO < /代码>可能来自任何地方,我们知道变量<代码> FoO 是“代码> Foo”类型< < /P>
如果您希望在运行时使用更具体的重载,您可以探索双重分派机制,例如。我不特别推荐的另一种方法是通过dynamic
关键字在运行时确定类型(如果问题已被很好地理解,通常会有更好的替代方法,但有时它是合适的)
运行时动态的语义是您可以在自己的时间内研究的,但这有效地产生了您似乎想要的结果。看起来您希望根据原始节点的运行时类型选择打印
。C正在选择编译时调用的函数-打印
不是虚拟方法,因此必须在编译时解析调用
你有吗
public SyntaxNode originalNode;
string print(BaseClassExtention Class)...
string print(BaseClass base)...
在编译时,将选择两个打印函数中的一个(基于ifSyntaxNode
是BaseClass
还是BaseClassExtension
)。如果SyntaxNode
派生自BaseClassExtension
,则使用字符串打印(BaseClassExtension类)
版本(因为它比基类
更具体,所以可以同时使用一个和另一个版本)
如果您想根据originalNode
的运行时类型使行为有所不同,您需要调用originalNode
的一些虚拟方法作为print
的一部分,或者手动检查类型并在print
方法内部执行某些操作。为什么它不知道?因为这太复杂了,无法理解请显示SyntaxNode的定义。正如@driis所述,您没有定义SyntaxNode
,它可以是任何东西,给变量起一个与关键字相同的名字,如base
,这是一个坏主意。您需要将其设为虚拟方法,然后重写它。此代码非常复杂很难阅读,因为您使用的“class”和“base”等词在C#中已经有了含义。您能提供一个简单、易读、完整的文件来说明您的问题吗?
public SyntaxNode originalNode;
string print(BaseClassExtention Class)...
string print(BaseClass base)...