And*_*ter 6 .net c# class-design
我有一个类似的问题在父方法中访问子项的访问静态属性.首选答案暗示类的设计有缺陷,需要更多信息来讨论问题.
这是我想和你讨论的情况.
我想实现一些单位感知数据类型,如长度,质量,当前,......应该有一个隐式转换来从给定的字符串创建实例.例如,"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");
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这给出了一个相当直观的用法,并使代码保持紧凑,可读性和可扩展性.但当然我遇到了引用帖子描述的相同问题.
现在我的问题是:如何通过设计避免这个问题?
我认为这可以通过泛型来解决,这样看起来仍然可读。根据 Slaks 建议进行改进,将注册放入静态构造函数中,使其本身线程安全。
所以如果我没记错的话:
SIConversion<Length>.GetFactor()(多 1 个字符)在派生类上实现所需的代码非常样板register(string,double);(实际上比字典定义短)
interface ISIConversionSubscriber
{
void Register(Action<string, double> regitration);
}
static class SIConversion<T> where T : ISIConversionSubscriber, new()
{
private static Dictionary<string, double> myConvertableUnits = new 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"));
}
}
Run Code Online (Sandbox Code Playgroud)输出:1
如果您想知道为什么我创建PhysicalQuantities抽象:以避免使用它,SIConversion<PhysicalQuantities>.GetFactor()因为我们没有基类的转换。无论如何,您可能不需要像这样的基类的实例 - 它不是数量的完整表示,因此它可能只包含可重用的方法。
另一个建议是使用 Enum 作为 baseUnit 而不是字符串。由于每个人都在努力实现类型安全并对魔法字符串大喊大叫,这可能是一条很好的道路:))
| 归档时间: |
|
| 查看次数: |
194 次 |
| 最近记录: |