C# 抽象妨碍了自定义类型的使用,在实现中应该遵循哪些规则?

C# 抽象妨碍了自定义类型的使用,在实现中应该遵循哪些规则?,c#,implementation,base-class,type-systems,C#,Implementation,Base Class,Type Systems,我已经构建了一个自定义类型系统,用于在应用程序中编写C#脚本。脚本是动态编译的,允许与应用程序内部数据交互。该类型系统是以抽象的方式设计的,使用的接口类似于IValue。IValue的实现可以是一个RefString、RefInteger、RefDouble(除其他外,这足以说明我的问题) 现在我们到了我被卡住的地步。。。使用这些IValue对象有些不自然。始终使用接口与对象交互被认为是一种良好的设计,但不可能为接口定义隐式转换或重载运算符。这会导致无法避免丑陋的显式转换,从而使用正确的运算符

我已经构建了一个自定义类型系统,用于在应用程序中编写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#In表达式,提供了隐式转换。设计这样一个定制系统的好方法是什么

我重写了typesystem,删除了
IValue
接口,并引入了
RefValue
基类。这样就可以消除显式强制转换的一部分。我在这个基类中实现了一些操作符重载,但是这给默认的转换操作符带来了很多麻烦。。。除此之外,运算符实现中要实现的逻辑还包含了许多关于系统中类型的知识。我认为这仍然是一条必须走的道路,但要以一种良好和安全的方式实施这条道路,需要遵循哪些规则

编辑:经过一段时间的努力,我可以找到一些规则:

  • 仅隐式声明基类型(int、double、string等)中的转换运算符
  • 声明对基类型的显式转换(以避免对int的隐式转换!!经常发生什么,但为什么?)
  • 为了避免不明确的调用,不应在基类和派生类中重写+、-、/、*运算符。[接下来该怎么办?我在派生类中执行了操作重载,这需要使用强制转换,这同样很难看…]

如果您应该能够对所有
IValue
执行
Add
操作,那么该界面可能应该包括
Add
方法?然后您可以执行
返回a.Add(b),并将如何执行操作的知识推送到每种类型中

一个问题是,现在看来,您可能会在
a
RefString
b
RefInteger
的地方得到调用,这可能不是您想要的。泛型可以帮助解决以下问题:

T Add<T>(T a, T b) where T : IValue
{
    return a.Add(b);
}
T添加(ta,tb),其中T:IValue
{
返回a.Add(b);
}

(当然,您需要添加空检查,如适用)

如果我使用
IValue b=6,则默认类型转换仍然存在问题例如。如果我在
RefInteger
类中有一个隐式转换运算符,则不能在接口中声明该运算符。涉及泛型的想法也许可以帮我省去一些麻烦,谢谢你的提示。像+、*、/、-这样的运算符不能在接口中声明,或者我遗漏了什么吗?@jdehaan:No,据我所知,在接口中声明运算符是没有办法的。我开始设计使用一个具体的类,使用一些允许的隐式转换,并以与ECMA 334标准中数字提升相同的方式强制转换其他类。这似乎至少可以提供良好的可读性代码并满足类型转换要求。谢谢你的帮助,我最终接受了你的答案,你是对的,因为在界面级别没有解决问题的可选方法。