Search code examples
c#clrvirtualsealedsealed-class

Why does the ordering of the unsealed class`s unsealed virtual methods calls matter?


Why does the ordering of the unsealed class`s unsealed virtual methods calls matter?

I am exploring the CLR via C# book and I come across the following excerpt:

When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. However, once a class is unsealed, you can never change it to sealed in the future as this would break all derived classes. In addition, if the unsealed class defines any unsealed virtual methods, ordering of the virtual method calls must be maintained with new versions or there is the potential of breaking derived types in the future.

Could someone explain the highlighted in bold part in a foolproof manner and (maybe) provide a few examples?

I understand what is the sealed/unsealed class/method and I understand what is a virtual method. But the thing which I do not understand is the ordering. What ordering is referred to in the excerpt?


Solution

  • Here's a scenario where maintaining the order of virtual method calls is important:

    class BaseClass
    {
        public int Answer { get; protected set; }
    
        protected virtual void VM1() { Answer += 20; }
        protected virtual void VM2() { Answer += 10; }
    
        public void Init() { VM1(); VM2(); }
    }
    
    class DerivedClass : BaseClass
    {
        private int _dividend;
    
        protected override void VM1() { Answer = _dividend = 20; }
        protected override void VM2() { Answer /= 10 }
    }
    

    Now let's say you have this somewhere:

    var baseObj = new BaseClass();
    baseObj.Init();
    int baseAnswer = baseObj.Answer;
    
    var derivedObj = new DerivedClass();
    derivedObj.Init();
    int derivedAnswer = derivedObj.Answer;
    

    baseAnswer will contain 30 and derivedAnswer will contain 2.

    Now, let's say Init() was changed so VM2() was called before VM1(). baseAnswer still contains 30 so everything looks okay. However, derivedAnswer will contain 20 (it was 2)! This is the kind of situation that I believe the book is warning you about.