0

Conditions: If a class(ep:A) inherits other class(ep:B).

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

class A:B
{
    public string className;
}    

When i create A's instance,then call id through A's instance

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

Problem: When I Call Main,CLR will check all Main's reference types and load these type into AppDomain.**

Now,I only reference A type - Will CLR load B?** I think B type will be loaded into AppDomain - But why?

Then,About dynamic memory problem? Will CLR give how much memory to A type?

The memory will contain B's fields? If as we expected,which ctor will initialize these fileds that come from B ? B's ctor? But it is noted that ctor can't be inherited. so,how we call the B's ctor? By base (key word) ? how does base get the B's ctor?

I want look for answer from IL Code: enter image description here

B::id made me confused.... i don't have B's instance,Can i call B::id? Who konws reasons for these problems, please explain to me! very very thx!!!

Community
  • 1
  • 1
MUYA
  • 37
  • 10
  • Is your concern with how to use inheritance, or how it was implemented by Microsoft? If B wasn't loaded, how would the compiler know that A has an id field? How would you be able to use it as B polymorphically? – ProgrammingLlama Nov 28 '18 at 03:21
  • @John How it was implemented by Microsoft? – MUYA Nov 28 '18 at 03:23
  • 1
    I don't have the answer to that. Why is this important to you? – ProgrammingLlama Nov 28 '18 at 03:26
  • If B was loaded,B's fields how to initialize? because i love programing,i don't want to be API user. – MUYA Nov 28 '18 at 03:31
  • [This answer should cover that](https://stackoverflow.com/questions/1882692/c-sharp-constructor-execution-order) – ProgrammingLlama Nov 28 '18 at 03:37
  • What problem are you trying to solve? Or do you need clarification on how to use inheritance in C#? – mr.coffee Nov 28 '18 at 03:39
  • 1
    What do you mean you don't want to be an API user? .NET is built of thousands of apis. If you're planning to do .NET, then you're going to be consuming apis. The answer to this question isn't going to make you more productive. If you want to do low level programming, then C# probably isn't for you. C or Rust will probably be more to your liking. – mason Nov 28 '18 at 03:41
  • @MUYA Decompile `A::.ctor()` and you will see, that it calls `B::.ctor()`. – user4003407 Nov 28 '18 at 03:45
  • @mason thx your ads.I am in awe of every language. – MUYA Nov 28 '18 at 03:57
  • @PetSerAI But Why A can call B::.ctor()?By reflection? – MUYA Nov 28 '18 at 03:58
  • @MUYA `B` have public constructor. Why `A` should not be able to call it. – user4003407 Nov 28 '18 at 04:06
  • @PetSerAl A class can call directly other class's ctor? As mentioned below,by A's ctor found b's ctor by metadata. – MUYA Nov 28 '18 at 04:10
  • @MUYA It have to call base class constructor, if it can not do that, then you will have compiler error. – user4003407 Nov 28 '18 at 04:15
  • @mr.coffee no problem need to be solved! only study – MUYA Nov 28 '18 at 04:15
  • 1
    @John thx your help! – MUYA Nov 28 '18 at 04:16
  • @PetSerAl I know it have to call base class ctor.But why can it be able to call base class ctor? this is my concern. – MUYA Nov 28 '18 at 04:18
  • @MUYA I do not understand your concern. Suppose language designer prohibit `A` to call base class constructor. What would be use of the language, where class have to call base class constructor, but it can not do that, because such call prohibited by language? – user4003407 Nov 28 '18 at 04:25
  • @PetSerAl i know it can be able to call.But i don't know why it can be able to call.This is my concern.hihihi – MUYA Nov 28 '18 at 04:32
  • @MUYA Because language designers decide so. – user4003407 Nov 28 '18 at 04:33
  • @PetSerAl ..................I prefer to konw the real reason. – MUYA Nov 28 '18 at 04:35
  • @MUYA Then you need to ask one of language designer, why them decide to design language this way, but not another. – user4003407 Nov 28 '18 at 04:40
  • @PetSerAl I am very lucky to have got the answer. – MUYA Nov 28 '18 at 04:44

1 Answers1

9

When I call Main, the CLR will check all types used in Main and load these types into the AppDomain.

No, that's not necessarily true. The type loader can load those types earlier if it wishes, or, in some cases, it can delay loading the types.

The mechanism you are assuming is that the jit compiler checks the set of types used by Main as it jits Main, and it loads any types that are used but not already loaded, and along the way it initializes static state for those types, right? That's an optimization that the jitter happens to make sometimes. It is not a guarantee of the C# language; C# only guarantees that if you have a static constructor, that it runs before the first instance is created or the first method is executed.

I only reference type A - will the CLR load type B?

Yes. All the dependencies of the type A must be loaded, and that includes the base type.

I think B type will be loaded into AppDomain, but why?

All the dependencies of the type A must be loaded, and that includes the base type.

The CLR gives how much memory to an instance of type A?

As much as it needs.

The memory will contain B's fields?

Yes.

Which ctor will initialize these fields that come from B ? B's ctor?

The memory allocator will initialize all the fields to their default values; if B's ctor then assigns a different value to the field, that happens when B's ctor runs.

But it is noted that ctor can't be inherited.

Correct. The ctor in B is not a member of type A.

how do we call the B ctor? By the base keyword?

Correct. If you do not include a base or this reference in your ctor, C# will automatically assume that you meant base(). If there is no matching accessible ctor, then the program is an error, and you must explicitly specify which base constructor you want to call.

how does base get the B ctor?

The compiler looks up the metadata token for the appropriate base class ctor and puts it in the implementation of the derived class ctor. You can use ILDASM apparently; use it to look at the A ctor and you'll see the call to the B ctor.

I don't have an instance of B

Yes you do. All A are instances of B. If you had a class Animal, and a class Giraffe that derived from Animal, and you have an instance of Giraffe, then you also have an instance of Animal, right?

Can I use id from B?

Obviously yes; you did!

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Thank you very much for your explanation.Help me understand that A's ctor call B's ctor by metadata.thx again. – MUYA Nov 28 '18 at 04:08
  • @MUYA: You're welcome. These articles that I wrote about constructors ten years ago might help you: https://blogs.msdn.microsoft.com/ericlippert/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one/ https://blogs.msdn.microsoft.com/ericlippert/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors-part-two/ https://ericlippert.com/2013/02/06/static-constructors-part-one/ – Eric Lippert Nov 28 '18 at 04:24