我对继承感到困惑

时间:2018-11-28 03:13:39

标签: c#

条件: 如果某个类(ep:A)继承了其他类(ep:B)。

class B
{
    public int id;
    public string Name;
}

class A:B
{
    public string className;
}    

创建A的实例时,然后通过A的实例调用ID

 static void Main(string[] args)
 {
      A a = new A();
      Console.WriteLine(a.id);
 }

问题: 当我致电Main时,CLR将检查所有Main的引用类型并将这些类型加载到AppDomain中。**

现在,我仅引用A类型-CLR是否会加载B?** 我认为B类型将被加载到AppDomain中-但是为什么呢?

然后,关于动态内存问题? CLR会为A类型分配多少内存吗?

内存将包含B的字段? 如果我们如预期的那样,哪个ctor将初始化来自B的这些文件? B的ctor? 但是要注意ctor不能被继承。 那么,我们怎么称呼B的ctor?是按基数(关键字)? 基地如何获得B的ctor?

我想从IL代码中寻找答案: enter image description here

B :: id让我感到困惑。...我没有B的实例,我可以叫B :: id吗? 谁知道这些问题的原因,请向我解释!非常非常感谢!!!

1 个答案:

答案 0 :(得分:9)

  

当我呼叫Main时,CLR将检查Main中使用的所有类型并将这些类型加载到AppDomain中。

不,不一定是真的。类型加载器可以根据需要提前加载这些类型,或者在某些情况下可以延迟加载这些类型。

您假设的机制是jit编译器在Main时检查Main使用的类型集,并加载所有已使用但尚未加载的类型。它为那些类型初始化静态的方式,对吗?这是抖动有时会产生的优化。它不是C#语言的保证; C#仅保证如果您具有静态构造函数,则该构造函数将在创建第一个实例或执行第一个方法之前运行。

  

我仅引用类型A-CLR会加载类型B吗?

是的。必须加载类型为A的所有依赖项,其中包括基本类型。

  

我认为B类型将被加载到AppDomain中,但是为什么呢?

必须加载类型为A的所有依赖项,其中包括基本类型。

  

CLR为类型A的实例提供多少内存?

根据需要。

  

内存将包含B的字段?

是的

  

哪个ctor将初始化来自B的这些字段? B的简历?

内存分配器会将所有字段初始化为其默认值;如果B的ctor然后为该字段分配了一个不同的值,则这种情况会在B的ctor运行时发生。

  

但是请注意,ctor不能被继承。

正确。 B中的ctor不是类型A的成员。

  

我们如何称呼B ctor?通过base关键字?

正确。如果您的ctor中未包含basethis引用,则C#将自动假定您的意思是base()。如果没有匹配的可访问ctor,则程序是错误的,您必须显式指定要调用的基本构造函数。

  

base如何获得B ctor?

编译器会为适当的基类ctor查找元数据令牌,并将其放入派生类ctor的实现中。您显然可以使用ILDASM。用它查看A ctor,您将看到对B ctor的调用。

  

我没有B的实例

是的。所有A都是B的实例。如果您有一个类Animal和一个从Giraffe派生的类Animal,并且您有一个Giraffe的实例,那么您也有一个{{1 }},对吧?

  

我可以使用Animal中的id吗?

显然是的;你做到了!