为了账号安全,请及时绑定邮箱和手机立即绑定

丰富枚举 - 可能吗?

丰富枚举 - 可能吗?

C#
大话西游666 2023-12-17 19:59:37
我正在寻找一种解决方案来将不可变数据存储在我的代码而不是数据库中。在具体情况下,我想处理单位。这是重量单位的示例(它们不会改变,所以可以将它们存储在我的代码中):public class Unit    {        public Unit() { }        public Unit(string name, string symbol, double factor, Unit baseUnit, UnitType unitType)        {            this.Name = name;            this.Symbol = symbol;            this.Factor = factor;            this.BaseUnit = baseUnit;            this.UnitType = unitType;        }        public int Id { get; set; }        public string Name { get; set; }        public UnitType UnitType { get; set; }        public string Symbol { get; set; }        public string NamePlural { get; set; }        public Unit BaseUnit { get; set; }        public double Factor { get; set; }    }    public static class TimeUnits    {        public static Unit second = new Unit("second", "s", 1, null, UnitTypes.Time);        public static Unit microsecond = new Unit("microsecond", "μs", 0.000001, second, UnitTypes.Time);        public static Unit millisecond = new Unit("millisecond", "ms", 0.001, second, UnitTypes.Time);        public static Unit minute = new Unit("minute", "min", 60.0, second, UnitTypes.Time);        public static Unit hour = new Unit("hour", "h", 3600.0, second, UnitTypes.Time);        public static Unit day = new Unit("day", "d", 24.0, hour, UnitTypes.Time);        public static Unit week = new Unit("week", "w", 7, day, UnitTypes.Time);    }如前所述,我不想将这些不可变信息存储在数据库中,以避免 ef-core 在从数据库检索数据时执行额外的联合。对于性别,我只需使用枚举: public enum Gender{    male = 1,    female = 2,    not_applicable = 9,    dont_want_to_share = 10}我想为单位提供类似的解决方案。但枚举只有一个 ID 和一个名称。对于上面显示的单位或其他情况,我需要额外的属性(例如,factore、unitType 等)。非常感谢您提供有关如何实现此目标的任何提示,以便 ef core 像使用枚举一样加载这些值。
查看完整描述

2 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

属性是一种方法,但如果您想避免使用反射,您可以实现一个包含您需要的所有内容的类,类似于:


public enum UnitType

{

    Second,

    Microsecond,

    Millisecond,

    Minute,

    Hour,

    Day,

    Week

}


public class Unit

{

    public string Name { get; private set; }


    public string Symbol { get; private set; }


    public double Factor { get; private set; }


    public Unit Base { get; private set; }


    public Unit(UnitType unit, bool isBase = false)

    {

        Name = GetUnitName(unit);


        Symbol = GetUnitSymbol(unit);


        Factor = GetUnitFactor(unit);


        if (!isBase)

            Base = GetUnitBase(unit);

    }


    private string GetUnitName(UnitType unit)

    {

        switch (unit)

        {

            case UnitType.Second:

                return "second";

            case UnitType.Microsecond:

                return "microsecond";

            case UnitType.Millisecond:

                return "millisecond";

            case UnitType.Minute:

                return "minute";

            case UnitType.Hour:

                return "hour";

            case UnitType.Day:

                return "day";

            case UnitType.Week:

                return "week";

            default:

                return null;

        }

    }


    private string GetUnitSymbol(UnitType unit)

    {

        switch (unit)

        {

            case UnitType.Second:

                return "s";

            case UnitType.Microsecond:

                return "μs";

            case UnitType.Millisecond:

                return "ms";

            case UnitType.Minute:

                return "min";

            case UnitType.Hour:

                return "h";

            case UnitType.Day:

                return "d";

            case UnitType.Week:

                return "w";

            default:

                return null;

        }

    }


    private double GetUnitFactor(UnitType unit)

    {

        switch (unit)

        {

            case UnitType.Second:

                return 1;

            case UnitType.Microsecond:

                return 0.000001;

            case UnitType.Millisecond:

                return 0.001;

            case UnitType.Minute:

                return 60.0;

            case UnitType.Hour:

                return 3600.0;

            case UnitType.Day:

                return 24.0;

            case UnitType.Week:

                return 7;

            default:

                return 0;

        }

    }


    private Unit GetUnitBase(UnitType unit)

    {

        switch (unit)

        {

            case UnitType.Microsecond:

                return new Unit(UnitType.Second, true);

            case UnitType.Millisecond:

                return new Unit(UnitType.Second, true);

            case UnitType.Minute:

                return new Unit(UnitType.Second, true);

            case UnitType.Hour:

                return new Unit(UnitType.Minute, true);

            case UnitType.Day:

                return new Unit(UnitType.Hour, true);

            case UnitType.Week:

                return new Unit(UnitType.Day, true);

            default:

                return null;

        }

    }



}

用法 :


// initiate a new Unit instance. 

var unit = new Unit(UnitType.Week);


// Get values

var name = unit.Name;

var symbol = unit.Symbol;

var factor = unit.Factor;


// In case if some units doesn't have base

if (unit.Base != null)

{

    var baseName = unit.Base.Name;

    var baseSymbol = unit.Base.Symbol;

    var baseFactor = unit.Base.Factor;


}

这只是一个简单的示例,尚未经过充分测试,只是向您展示另一种可以实现的方法。


您还可以使用隐式运算符来获取值 例子 :


public class Unit

{

  ......


    public static implicit operator double(Unit v) => v.Factor;


    public static implicit operator string(Unit v) => v.Symbol;


}

隐式获取值:


var symbol = (string) unit; // will return the v.Symbol

var factor = (double) unit; // will return the v.Factor

此外,我没有展示UnitTypes.Time,因为没有太多关于它的代码,但我认为示例和想法足以为您的想法提供所需的推动力。


查看完整回答
反对 回复 2023-12-17
?
繁华开满天机

TA贡献1816条经验 获得超4个赞

我不确定你到底想做什么,但我认为属性将是一个不错的选择。您可以像这样在每个单元枚举字段上设置属性,并在需要时通过反射检索它们。


    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]

sealed class UnitTypeAttribute : Attribute

{

    public UnitType UnitType{ get; set; }

    public UnitAttribute(UnitType unitT)

    {

        UnitType= unitT;

    }

}


    enum Unit

{

    [UnitType(UnitTypes.Time)]

    Second,


    [UnitType(UnitTypes.Time)]

    MicroSecond,


    [UnitType(UnitTypes.Time)]

    Hour

}

然后,当你想检索它时,使用此方法(可以通用)


       public static UnitType GetUnitTypeAttribute(Unit unit)

    {

        var memberInfo = typeof(Unit).GetMember(unit.ToString());

        var result = memberInfo[0].GetCustomAttributes<UnitTypeAttribute>(false)


        return ((UnitType)result).UnitType;

    }


查看完整回答
反对 回复 2023-12-17
  • 2 回答
  • 0 关注
  • 144 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信