抽象阻碍自定义类型的使用,实施中需要遵循哪些规则?
-
28-09-2019 - |
题
我已经在应用程序中的C#脚本中构建了一个自定义类型系统。这些脚本是直接编译的,并允许与应用程序内部数据进行交互。此型型系统的设计是使用诸如 IValue
. 。实施 IValue
可以是一个 RefString
, RefInteger
, RefDouble
(除其他许多地方,但这足以证明我的问题)。
现在我们到了我被卡住的地步...使用这些 IValue
对象有些不自然。它被认为是始终使用接口与对象交互的好设计,但是没有可能定义隐式转换或对接口的运算符过载。这使得不可避免的丑陋明确铸造的情况使正确的操作员可以使用。
例子:
IValue Add(IValue a, IValue b)
{
//return a+b; // won't work: which operator +() to use?
return (RefInteger)a + (RefInteger)b;
}
对于涉及价值类型的表达式中的c#,提供了隐式转换。设计这样的自定义系统的好方法是什么?
我重写了典型系统的删除 IValue
接口并引入 RefValue
基类。这样,已经可以消除显式演员的一部分。我在此基类中实现了一些操作员的过载,但这造成了默认转换操作员的很多麻烦……除此之外,在操作员实施中实现的逻辑牵涉到有关系统中类型的大量知识。我认为这仍然是人们必须走的方式,但是要以良好和安全的方式实施它的规则是什么?
编辑: :挣扎过一会儿后,我发现的一些规则是:
- 仅从基本类型(int,double,string,...)声明隐式转换算子
- 将明确转换为基础类型(避免隐含的铸件!
- 为了避免模棱两可的调用 +, - , /, *在基类和派生类中不应覆盖运算符。 [那怎么办?我在派生的类中进行了操作过载,这需要在使用时施放,这再次丑陋...
解决方案
如果您应该能够 Add
所有人的操作 IValue
S,也许接口应包括一个 Add
方法?那你可以做 return a.Add(b);
, ,并推动如何将操作执行到每种类型的知识。
一个问题是,正如现在看起来,您可以在哪里接听电话 a
是 RefString
和 b
是 RefInteger
, ,这可能不是您想要的。仿制药可以帮助解决:
T Add<T>(T a, T b) where T : IValue
{
return a.Add(b);
}
(当然,您需要添加无效检查,以便适当)
不隶属于 StackOverflow