加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 我应该使用什么模式来表达层次枚举?

发布时间:2020-12-15 07:45:53 所属栏目:百科 来源:网络整理
导读:我正在尝试使用API??在给定时间发布值(值和时间的元组).这些样本将由数据查看器(例如图表)使用. 我想将值与数量和单位相关联,例如以米为单位的长度.这样我的“观察者”可以适当地缩放它. 我正在寻找一种分层枚举,如下所示: enum Quantity{ Mass.Kg,Mass.g,L
我正在尝试使用API??在给定时间发布值(值和时间的元组).这些样本将由数据查看器(例如图表)使用.

我想将值与数量和单位相关联,例如以米为单位的长度.这样我的“观察者”可以适当地缩放它.

我正在寻找一种分层枚举,如下所示:

enum Quantity
{
   Mass.Kg,Mass.g,Length.m,Length.mm
}

但这在C#中不存在.

我不确定表达这个的最佳模式,我想出了以下内容.有没有公??认的或更好的方法来做到这一点?

using System;
using Moq;

namespace ConsoleApplication26
{
    class Program
    {
        static void Main(string[] args)
        {
            //use a Mock to play with the API
            Mock<ITelemetryPublisherFactory> mockTelemetryPublisherFactory = new Mock<ITelemetryPublisherFactory>();
            var telemetryPublisherFactory = mockTelemetryPublisherFactory.Object;

            //example usages
            var massTelemetryPublisher = telemetryPublisherFactory.GetChannelSamplePublisher<Double>("My Mass",Mass.Kg);
            massTelemetryPublisher.PublishChannelSampleAtTimeNow(83.4);                        

            var lengthTelemetryPublisher = telemetryPublisherFactory.GetChannelSamplePublisher<Int32>("My Height",Length.μm);
            lengthTelemetryPublisher.PublishChannelSampleAtTimeNow(1800000);      

            //10 years time..
            lengthTelemetryPublisher.PublishChannelSampleAtTimeNow(1800000);
            massTelemetryPublisher.PublishChannelSampleAtTimeNow(120.1);                        
        }
    }

    public interface ITelemetryPublisherFactory
    {
        ITelemetryPublisher<T> GetChannelSamplePublisher<T>(String channelName,Quantity quantity);
    }

    public interface ITelemetryPublisher<T>
    {
        void PublishChannelSampleAtTimeNow(T sampleValue);
    }

    public abstract class Quantity {}

    public class Mass : Quantity
    {
        private enum Unit
        {
            g,Kg
        }

        private readonly Unit _unit;

        private Mass(Unit unit)
        {
            _unit = unit;
        }

        public static Quantity Kg {get { return new Mass(Unit.Kg); }}
        public static Quantity g { get { return new Mass(Unit.g); } }

        public override string ToString()
        {
            return String.Format("Mass.{0}",_unit);
        }
    }

    public class Length : Quantity
    {
        private enum Unit
        {
            m,mm,μm,beardSecond
        }

        private readonly Unit _unit;

        private Length(Unit unit)
        {
            _unit = unit;
        }

        public static Quantity m { get { return new Length(Unit.m); } }
        public static Quantity mm { get { return new Length(Unit.mm); } }
        public static Quantity μm { get { return new Length(Unit.μm); } }
        public static Quantity beardSecond { get { return new Length(Unit.beardSecond); } }

        public override string ToString()
        {
            return String.Format("Length.{0}",_unit);
        }        
    }    
}

解决方法

我认为最好为度量单位创建一个Unit类,并将一个度量单位与一个量相关联的Quantity类.看看 Quantity pattern的想法.由于您还想记录度量单位的“类型”,因此可以创建一个记录该信息的UnitType类:
public sealed partial class UnitType {
  public string Name { get; private set; }
  public UnitType(string name) {
    Name = name;
  }
}

public sealed partial class Unit {
  public string Name { get; private set; }
  public UnitType Type { get; private set; }
  public Unit(string name,UnitType type) {
    Name = name;
    Type = type;
  }
}

(您应该通过重写Equals和GetHashCode使它们成为正确的值类型)

Unit类可以扩展为例如转换,复合单元,格式化和解析.

然后,您可以在类中定义常见情况:

public partial class UnitType {
  public static readonly UnitType Mass = new UnitType("Mass");
  public static readonly UnitType Length = new UnitType("Length");
}

public partial class Unit {
  public static readonly Unit Grams = new Unit("g",UnitType.Mass);
  public static readonly Unit Kilos = new Unit("kg",UnitType.Mass);
  // ...
}

或者使用静态类定义“层次结构”:

public static class Mass {
  public static readonly UnitType Type = new UnitType("Mass");

  public static readonly Unit Grams = new Unit("g",Type);
  public static readonly Unit Kilos = new Unit("kg",Type);
  ...
}

public static class Length ...

Quantity类也是一个不可变的值类型(只显示其用法):

var eniacWeight = new Quantity(27,Mass.Tons);

或者您可以使用扩展方法来创建数量:

var eniacWeight = 27.Tons();

(自ENIAC起)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读