繁体   English   中英

类型安全的枚举和隐式运算符

[英]typesafe enum and implicit operator

我创建了一个实现typesafe枚举模式的Unit类。 我在其中实现了一个implicit operator以简化其用法。 但是我想将隐式运算符从string重构为Unit 当前,我使用的是switch块,但是一旦添加更多单元,这将变得非常快。 我当前的代码如下所示。

[DataContract]
public class Unit
{
    public static readonly Unit USFeet = new Unit("US Feet", 1);
    public static readonly Unit Meters = new Unit("Meters", 0.3048006096);
    [DataMember] public double ConversionConstant { get; private set; }
    [DataMember] private string Name { get; set; }

    private Unit(string name, double conversionConstant)
    {
        Name = name;
        ConversionConstant = conversionConstant;
    }
    public override string ToString()
    {
        return Name;
    }

    public static implicit operator string(Unit unit)
    {
        return unit.Name;
    }

    public static implicit operator Unit(string name)
    {
        switch (name)
        {
            case "US Feet":
                return USFeet;
            case "Meters":
                return Meters;
            default:
                return null;
        }
    }
}

所以我的问题是,有没有比使用switch模块更好的方法来解决这个问题?

我尝试过类似的操作,但是不起作用...

    public static SortedList<string, Unit> UnitList = new SortedList<string, Unit>();
    private Unit(string name, double conversionConstant)
    {
        Name = name;
        ConversionConstant = conversionConstant;
        UnitList.Add(name, this);
    }
    public static implicit operator Unit(string name)
    {
        return UnitList[name];
    }

您可以构建查找表,然后从.ctor更新它:

private static Dictionary<string, Unit> definedUnits = new Dictionary<string, UserQuery.Unit>();

private Unit(string name, double conversionConstant)
{
    Name = name;
    ConversionConstant = conversionConstant;

    definedUnits.Add(name, this);
}

public static implicit operator Unit(string name)
{
    Unit result;

    return definedUnits.TryGetValue(name, out result) ? result : null;
}

您还可以使用反射动态构建该表:

private static Dictionary<string, Unit> definedUnits = typeof(Unit)
    .GetFields(BindingFlags.Public | BindingFlags.Static)
    .Where(x => x.IsInitOnly && x.FieldType == typeof(Unit))
    .ToDictionary(x => x.Name, x => (Unit)x.GetValue(null));

看来我在上面尝试过的方法可以像这样完成工作(我认为这称为延迟初始化)

[DataContract]
public class Unit
{

    public static readonly Unit USFeet = new Unit("US Feet", 1);
    public static readonly Unit Meters = new Unit("Meters", 0.3048006096);

    private static Dictionary<string, Unit> _unitList;
    public static readonly Dictionary<string, Unit> UnitList = _unitList ?? (_unitList = new Dictionary<string, Unit>());

    [DataMember] private readonly double _conversionConstant;
    [DataMember] private readonly string _name;

    private Unit(string name, double conversionConstant)
    {
        _name = name;
        _conversionConstant = conversionConstant;
        UnitList.Add(name, this);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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