Enum “Inheritance”

后端 未结 15 1476
野性不改
野性不改 2020-11-22 07:21

I have an enum in a low level namespace. I\'d like to provide a class or enum in a mid level namespace that \"inherits\" the low level enum.

namespace low
{
         


        
相关标签:
15条回答
  • 2020-11-22 08:16

    This is not possible (as @JaredPar already mentioned). Trying to put logic to work around this is a bad practice. In case you have a base class that have an enum, you should list of all possible enum-values there, and the implementation of class should work with the values that it knows.

    E.g. Supposed you have a base class BaseCatalog, and it has an enum ProductFormats (Digital, Physical). Then you can have a MusicCatalog or BookCatalog that could contains both Digital and Physical products, But if the class is ClothingCatalog, it should only contains Physical products.

    0 讨论(0)
  • 2020-11-22 08:20

    I know this answer is kind of late but this is what I ended up doing:

    public class BaseAnimal : IEquatable<BaseAnimal>
    {
        public string Name { private set; get; }
        public int Value { private set; get; }
    
        public BaseAnimal(int value, String name)
        {
            this.Name = name;
            this.Value = value;
        }
    
        public override String ToString()
        {
            return Name;
        }
    
        public bool Equals(BaseAnimal other)
        {
            return other.Name == this.Name && other.Value == this.Value;
        }
    }
    
    public class AnimalType : BaseAnimal
    {
        public static readonly BaseAnimal Invertebrate = new BaseAnimal(1, "Invertebrate");
    
        public static readonly BaseAnimal Amphibians = new BaseAnimal(2, "Amphibians");
    
        // etc        
    }
    
    public class DogType : AnimalType
    {
        public static readonly BaseAnimal Golden_Retriever = new BaseAnimal(3, "Golden_Retriever");
    
        public static readonly BaseAnimal Great_Dane = new BaseAnimal(4, "Great_Dane");
    
        // etc        
    }
    

    Then I am able to do things like:

    public void SomeMethod()
    {
        var a = AnimalType.Amphibians;
        var b = AnimalType.Amphibians;
    
        if (a == b)
        {
            // should be equal
        }
    
        // call method as
        Foo(a);
    
        // using ifs
        if (a == AnimalType.Amphibians)
        {
        }
        else if (a == AnimalType.Invertebrate)
        {
        }
        else if (a == DogType.Golden_Retriever)
        {
        }
        // etc          
    }
    
    public void Foo(BaseAnimal typeOfAnimal)
    {
    }
    
    0 讨论(0)
  • 2020-11-22 08:20

    Alternative solution

    In my company, we avoid "jumping over projects" to get to non-common lower level projects. For instance, our presentation/API layer can only reference our domain layer, and the domain layer can only reference the data layer.

    However, this is a problem when there are enums that need to be referenced by both the presentation and the domain layers.

    Here is the solution that we have implemented (so far). It is a pretty good solution and works well for us. The other answers were hitting all around this.

    The basic premise is that enums cannot be inherited - but classes can. So...

    // In the lower level project (or DLL)...
    public abstract class BaseEnums
    {
        public enum ImportanceType
        {
            None = 0,
            Success = 1,
            Warning = 2,
            Information = 3,
            Exclamation = 4
        }
    
        [Flags]
        public enum StatusType : Int32
        {
            None = 0,
            Pending = 1,
            Approved = 2,
            Canceled = 4,
            Accepted = (8 | Approved),
            Rejected = 16,
            Shipped = (32 | Accepted),
            Reconciled = (64 | Shipped)
        }
    
        public enum Conveyance
        {
            None = 0,
            Feet = 1,
            Automobile = 2,
            Bicycle = 3,
            Motorcycle = 4,
            TukTuk = 5,
            Horse = 6,
            Yak = 7,
            Segue = 8
        }
    

    Then, to "inherit" the enums in another higher level project...

    // Class in another project
    public sealed class SubEnums: BaseEnums
    {
       private SubEnums()
       {}
    }
    

    This has three real advantages...

    1. The enum definitions are automatically the same in both projects - by definition.
    2. Any changes to the enum definitions are automatically echoed in the second without having to make any modifications to the second class.
    3. The enums are based on the same code - so the values can easily be compared (with some caveats).

    To reference the enums in the first project, you can use the prefix of the class: BaseEnums.StatusType.Pending or add a "using static BaseEnums;" statement to your usings.

    In the second project when dealing with the inherited class however, I could not get the "using static ..." approach to work, so all references to the "inherited enums" would be prefixed with the class, e.g. SubEnums.StatusType.Pending. If anyone comes up with a way to allow the "using static" approach to be used in the second project, let me know.

    I am sure that this can be tweaked to make it even better - but this actually works and I have used this approach in working projects.

    Please up-vote this if you find it helpful.

    0 讨论(0)
提交回复
热议问题