c# - C# 中任意对象的数学运算

标签 c# object

我正在用 C# 实现玩具语言的解释器,为了用该语言进行数学计算,我想实现如下函数:

public static object Add( object a, object b )
{
  // return the sum of a and b
  // each might be int, double, or one of many other numeric types
}

我可以想象这个函数的一个非常愚蠢和糟糕的实现,它有大量基于 a 和 b 类型的分支(使用 is 运算符)和一堆强制转换,但我的直觉是有更好的方法。

您认为该功能的良好实现方式是什么?

最佳答案

如果:

  • 您只需要一个易于编程的解决方案
  • 你的小语言有和 C# 一样的算术规则
  • 你可以使用 C# 4
  • 您并不特别关心性能

那么你可以简单地这样做:

public static object Add(dynamic left, dynamic right)
{
    return left + right;
}

完成。调用此方法时会发生什么,代码将再次启动 C# 编译器 并询问编译器“如果必须添加这两个东西,你会怎么做,但你知道它们的运行时类型编译时间?” (然后动态语言运行时将缓存结果,以便下次有人尝试将两个整数相加时,编译器不会再次启动,它们只是重新使用编译器返回给 DLR 的 lambda。)

如果你想实现自己的加法规则,欢迎来到我的世界。没有什么神奇的方法可以避免大量的类型检查和转换。确实有 数百 两种任意类型相加的可能情况,您必须检查所有情况。

我们在 C# 中处理这种复杂性的方法是在较小的类型子集上定义加法运算符:int、uint、long、ulong、decimal、double、float、所有枚举、所有委托(delegate)、字符串和所有可为 null 的版本这些值类型。 (然后将枚举视为它们的基础类型,这进一步简化了事情。)

例如,当您将 ushort 添加到 short 时,我们通过说 ushort 和 short 都是 int 的特例来简化问题,然后解决添加两个 int 的问题。这大大减少了我们必须编写的代码量。但请相信我,C# 中的二元运算符重载解析算法有数千行代码。这不是一个简单的问题。

如果您的玩具语言旨在成为具有自己规则的动态语言,那么您可以考虑实现 IDynamicMetaObjectProvider 并使用 DLR 机制来实现算术和函数调用等其他操作。

关于c# - C# 中任意对象的数学运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3355819/

相关文章:

javascript - 模拟 'class' 时,为什么要在 .prototype 属性中而不是在构造函数本身中设置方法?

c# - 在 C# 中指定要与 TCPClient/Socket 一起使用的传出 IP 地址

c# - C# 中小型数组与小型结构的访问时间

c# - 使用 LINQ to Entities 获取最后一个字符索引

c# - 我应该只移动文件还是创建一个移动它的类?

python - 为什么 'is' 运算符说这些方法不一样?

Javascript对象原型(prototype)错误

javascript - 使用 .map() 向数组中存在的对象添加新属性

c# - string.ToLower() 和 string.ToLowerInvariant()

java - 为什么在Java链表遍历中使用递归不能返回Object?