What's the best C# pattern for implementing a hierarchy with an enum?

前端 未结 3 725
情深已故
情深已故 2021-02-14 17:10

I\'m implementing value types which represents a distance (or length). There\'s an enum that represents the different units of measure, eg:

public enum Distance         


        
相关标签:
3条回答
  • 2021-02-14 17:11

    Maybe all you need is a function that returns a corresponding unit subset

    class UnitSystem
    {
      public enum Type
      {
        Metric,
        Imperial
      }
    
      public static DistanceUnit[] GetUnits(Type type)
      {
        switch (type)
        {
          case Type.Metric:
            return new DistanceUnit[] {
              DistanceUnit.Millimeter,
              DistanceUnit.Centimeter,
              DistanceUnit.Meter,
              DistanceUnit.Kilometer
            }
    
          case Type.Imperial:
            return new DistanceUnit[] {
              DistanceUnit.Inch,
              DistanceUnit.Foot,
              DistanceUnit.Yard,
              DistanceUnit.Mile
            }
        }
      }
    
      public static Type GetType(DistanceUnit unit)
      {
        switch (unit)
        {
          case DistanceUnit.Millimeter:
          case DistanceUnit.Centimeter:
          case DistanceUnit.Meter:
          case DistanceUnit.Kilometer:
            return Type.Metric;
    
          case DistanceUnit.Inch:
          case DistanceUnit.Foot:
          case DistanceUnit.Yard:
          case DistanceUnit.Mile:
            return Type.Imperial;
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-14 17:27

    Generally speaking, I would go with Anton's solution. But if your implementation can't use that, and you need things to be used similar to an enum, I think this is a natural way to use the units:

    DistanceUnit.Metric.Millimeter  
    DistanceUnit.Imperial.Inch  
    

    In order to use it like that, there should be:

    public static class DistanceUnit  
    {
      public static MetricDistanceUnit Metric;
      public static ImperialDistanceUnit Imperial;
    }   
    

    Where MetricDistanceUnit is:

    public enum MetricDistanceUnit  
    {
       Millimeter, Centimeter ...
    }
    

    And ImperialDistanceUnit has the same structure..

    0 讨论(0)
  • 2021-02-14 17:36

    Do you really need an enum here? Maybe, a simple value object will do?

    public class Distance
    {
        private readonly decimal millimeters;
    
        public decimal Meters
        { 
            get { return millimeters * 0.001m; } 
        }
    
        private Distance(decimal millimeters)
        {
            this.millimeters = millimeters;
        }
    
        public static Distance Yards(decimal yards)
        {
            return new Distance(yards * 914.4m);
        }
    }
    

    With extension methods you and properly defined operators can get very Ruby-like syntax:

    var theWholeNineYards = 9.Yards() + 34.Inches();
    
    0 讨论(0)
提交回复
热议问题