简体   繁体   中英

Hidden Inherritance c#

In c#, is it possible to prevent the programmer to inherit a parent class, but allow child classes to be inherited from (perhaps just during the writing of the code, not during runtime)?

For example:

//Class which should only allow 'RangedAbility' and 'MeleeAbility' to inherit. 
//No other classes are to be allowed to inherit from Ability
public abstract class Ability{ 
    public virtual void foo(){}
}

public class RangedAbility : Ability{
     //an empty class
}
public class MeleeAbility : Ability{
     //an empty class
}

public class myAbility : MeleeAbility{
     public override void foo(){ /*some code*/}
} 
//attempting to inherit from `Ability` instead of `MeleeAbility` or instead of 'RangedAbility' 
//should result in programmer facing an error in IDE such as Visual Studio.

Using "sealed" on Ability will not work (it is abstract, as well as RangedAbility , MeleeAbility need to inherit from it). Reflection approach to "simmulate" inheritance by those two child classes would be very tedious and had to be done in both MeleeAbility and RangedAbility . Abandoning the use of Ability completely, and forcing RangedAbility and MeleeAbility to implement an interface doesn't seem like a good option either, because they share methods that would be better-off written once through a "hidden" parent class.

The reason for doing such code is that I need to determine at runtime what kind of behavior to expect from 'myAbility' type. It is done through IsSubclassOf(typeof(MeleeAbility)) or IsSubclassOf(typeof(RangedAbility)) , which allows to determine expected behavior without needing an actual instance of myAbility .

public abstract class Ability
{
  internal Ability()
  {
  }

  public virtual void foo(){}
}

Because the only constructor for Ability is internal only a derived class from within the same assembly can be constructed (constructors that don't explicitly build on a base constructor are implicitly : base() ). Any attempt for a class in another assembly to derive directly from Ability will not have a valid constructor.

(On a related note, you might find an internal abstract property that your own classes override to return different values as neater method of determining which you have than doing explicit IsSubClassOf or even is tests. Or better again, providing whatever functionality turns on such a test through an internal abstract method).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM