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

c# – 在父方法中访问子节点的静态属性 – 设计注意事项

发布时间:2020-12-15 08:28:59 所属栏目:百科 来源:网络整理
导读:我在 Accessing a static property of a child in a parent method之后遇到了类似的问题.首选答案提示类的设计有缺陷,需要更多信息来讨论问题. 这是我想和你讨论的情况. 我想实现一些单位感知数据类型,如长度,质量,当前,… 应该有一个隐式转换来从给定的字符
我在 Accessing a static property of a child in a parent method之后遇到了类似的问题.首选答案提示类的设计有缺陷,需要更多信息来讨论问题.

这是我想和你讨论的情况.

我想实现一些单位感知数据类型,如长度,质量,当前,…
应该有一个隐式转换来从给定的字符串创建实例.例如,“1.5米”应与“150厘米”相同,或“20英寸”应正确处理.

为了能够在不同的单位之间进行转换,我需要特定数量的转换常数.
我的想法是创建一个带有一些静态翻译方法的抽象基类.
那些应该使用特定于类的静态字典来完成它们的工作.
那么看看这个例子吧.

public class PhysicalQuantities
{
    protected static Dictionary<string,double> myConvertableUnits;

    public static double getConversionFactorToSI(String baseUnit_in)
    {
        return myConvertableUnits[baseUnit_in];
    }
}

public class Length : PhysicalQuantities
{
    protected static Dictionary<string,double> myConvertableUnits = new Dictionary<string,double>()
    {
        { "in",0.0254 },{ "ft",0.3048 }
    };
}

class Program
{
    static void Main(string[] args)
    {
        Length.getConversionFactorToSI("in");
    }
}

我认为这给出了一个相当直观的用法,并使代码保持紧凑,可读性和可扩展性.但当然我遇到了引用post描述的相同问题.

现在我的问题是:如何通过设计避免这个问题?

解决方法

我认为这可以用泛型来解决,看起来仍然可读.根据Slaks的建议进行细化,以使注册适合静态构造函数,使其本身具有线程安全性.

所以如果我没有弄错的话:

>线程安全(所有工作在静态构造函数中的字典)
>语法仍然易于使用和可读SIConversion< Length> .GetFactor()(1个字符更多)
>需要在派生类上实现的代码非常样板寄存器(string,double); (实际上比你的字典定义短)

interface ISIConversionSubscriber
{
    void Register(Action<string,double> regitration);
}

static class SIConversion<T> where T : ISIConversionSubscriber,new()
{

    private static Dictionary<string,double>();

    static SIConversion() {
        T subscriber = new T();
        subscriber.Register(registrationAction);
    }

    public static double GetFactor(string baseUnit)
    {
        return myConvertableUnits[baseUnit];
    }

    private static void registrationAction(string baseUnit,double value)
    {
        myConvertableUnits.Add(baseUnit,value);
    }

}

abstract class PhysicalQuantities : ISIConversionSubscriber
{
    public abstract void Register(Action<string,double> register);
}

class Length : PhysicalQuantities
{
    public override void Register(Action<string,double> register)
    {
        // for each derived type register the type specific values in this override
        register("in",1);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(SIConversion<Length>.GetFactor("in"));
    }
}

输出:1

如果你想知道为什么我将PhysicalQuantities抽象化:避免将它与SIConversion< PhysicalQuantities> .GetFactor()一起使用,因为我们没有基类的转换.您可能不需要像这样的基类实例 – 它不是数量的完整表示,因此它可能只包含可重用的方法.

另一个建议是使用Enum作为baseUnit而不是字符串.既然每个人都在努力争取类型安全并且在魔术弦上大声吵嚷,那么它可能是一条很好的路径:))

(编辑:李大同)

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

    推荐文章
      热点阅读