C#编译器如何区分抽象方法的具体子类impl和抽象基中的重载?
如果你有一个基类C#编译器如何区分抽象方法的具体子类impl和抽象基中的重载?,c#,.net,generics,compiler-construction,overloading,C#,.net,Generics,Compiler Construction,Overloading,如果你有一个基类 public abstract class AbsHashtableish<TKey, TValue> { public abstract TKey ConvertToKey(string key); public abstract bool KeyExists(TKey key); public virtual bool KeyExists(string key) { Console.WriteLine("In
public abstract class AbsHashtableish<TKey, TValue>
{
public abstract TKey ConvertToKey(string key);
public abstract bool KeyExists(TKey key);
public virtual bool KeyExists(string key)
{
Console.WriteLine("In Base");
return KeyExists(ConvertToKey(key));
}
}
公共抽象类AbsHashtableish
{
公共抽象TKey CONVERTOKEY(字符串键);
公共抽象布尔键存在(TKey);
公共虚拟布尔键存在(字符串键)
{
控制台。写入线(“在底部”);
返回键存在(ConvertToKey(键));
}
}
还有一节混凝土课
public class ConcreteHashtableish: AbsHashtableish<string, Dinosaur>
{
...
public override string ConvertToKey(string key)
{
return key;
}
public override bool KeyExists(string key)
{
Console.WriteLine("In Sub");
return _list.Contains(key);
}
}
public类ConcreteHashtableish:AbsHashtableish
{
...
公共重写字符串转换键(字符串键)
{
返回键;
}
公共覆盖布尔键存在(字符串键)
{
控制台。写入线(“子系统”);
返回_list.Contains(键);
}
}
客户A
AbsHashtableish<string, Dinosaur> concreteA = new ConcreteHashtableish<string, Dinosaur>();
AbsHashtableish concreteA=new ConcreteHashtableish();
和客户B
ConcreteHashtableish<string, Dinosaur> concreteB = new ConcreteHashtableish<string, Dinosaur>();
ConcreteHashtableish concreteB=new ConcreteHashtableish();
确定上面显示的代码是否足以编译的规则是什么(如果可能,还有背后的推理),如果可以:
concreteA
上调用KeyExists
与concreteB
之间是否有区别keyissets(string-key)
,那么我们能从中解脱出来吗对于问题#2,我的意思是,如果编译器能够以某种方式编译这段代码,它是否通过有效地向客户机隐藏基本方法来做到这一点——因为如果达到了这段代码,这将导致无限循环?在
convreteA
和concrete上调用KeyExists
最终是相同的
公共语言运行库(CLR)
知道调用实际类型上的方法(使用)。这就是我的全部观点。它允许您将具体实现称为抽象实现,但实际调用的方法属于具体类型
在您给出的特定示例中,您不能从派生类外部使用KeyExists
的基类实现,因为您不能创建抽象类的实例。如果不是抽象的,您可以创建:
AbsHashtableish<string, Dinosaur> baseA = new AbsHashtableish<string, Dinosaur>();
在具体类中,您可以通过使用base.KeyExists(key)
@AndroidJoker调用基实现。因此,可以公平地说,编译器向CLR编写的指令是“调用KeyExists的这个或那个特定实现”,或者改为“Call KeyExists,我知道到时候你会知道的。”@tacos\u tacos\u tacos:Down在IL代码中只显示“Call KeyExists”“然后运行时将查看该类的vtable。有一个指向应该调用的方法的指针,如果派生类重写了它,它将指向具体实现,否则指向基实现。当运行时加载类型时,会创建vtable内容。但我不是专家,所以如果我弄错了什么,任何人都可以纠正我。
base.KeyExists(key)