【问题标题】:Less generic generics? A possible solution for arithmetic in C# generics [duplicate]泛型较少? C#泛型中算术的可能解决方案[重复]
【发布时间】:2010-11-29 19:25:19
【问题描述】:

目前,C# 中的泛型不允许任何理智的方式来执行算术。有一些笨拙的解决方法可用,但它们都不是很整洁,而且都降低了性能。 根据this interview,无法实现具有算术类型的接口,因此建议使用这样的解决方法。

但是你可以做的是让你的矩阵作为一个计算器的参数,在计算器中,有一个称为乘法的方法。你去实现它并将它传递给矩阵。

为什么我必须告诉高级编程语言如何加法和乘法? [因大众需求而编辑]

为什么不简单地将泛型限制为类型列表?

例如。

class Matrix<T> where T : int,long,float,double

语法当然可以不同。但是编译器只需要检查该类型是否在列表中,以及使用的运算符是否适用于所有类型,这应该比看似太难的接口建议要简单得多。

是否有任何明显的原因说明为什么无法实施?

【问题讨论】:

  • 这个问题回答了你的问题:stackoverflow.com/questions/32664/…
  • 不,它没有。它部分回答了一系列类似的问题,但最重要的问题(考虑到最后发布的“答案”)没有得到解答。
  • -1:主观/争论。 “这太愚蠢了……他甚至暗示这表明 C# 开发人员是多么有限。”
  • 建议:您的问题似乎过于抽象,也许您可​​以添加一个示例,说明您想要做什么以及应该导致什么。
  • 我是否可以建议您将其表述为“为什么不实施此应该?”。正如 Eric 所说,这可以由一个足够称职的开发人员来完成(尽管我很遗憾负责让小数像其他人一样工作的可怜人),就像大多数编程语言设计一样,它是关于权衡的。表现出你理解这一点(以及一些礼貌)会让你得到更好的回应......

标签: c# generics types math


【解决方案1】:

泛型不是 C++ 模板。编译器将只允许对它可以验证对这些参数有效的泛型类型参数进行操作,因为要使用的确切类型在 JIT 编译之前不会插入。 C++ 在编译时进行插入,并不关心一个操作是否对 T 的每个可能值都有效,只要它对您实际使用的 T 的特定值有效。

此外,像 where T : int 这样的约束是没有意义的,因为不能有任何类型从 int 派生,因为 int 是一个结构。遵守此约束的唯一类型是 int 本身。如果您知道您的类型将始终为 int,那么泛型将变得毫无意义。

【讨论】:

  • 我知道它们不是 C++ 模板,这不是我想要的。 C++ 模板很容易导致运行时错误......对于特定类型的列表,这应该是不可能的,因为可以在编译时检查所有类型。至于第二点,没有理智的人会使用“T : int”。您可能会注意到,我列出了四种类型,而不是一种。重点是减少代码重复,因此我可以编写一个“通用”矩阵,而不是为每种类型编写一个。
【解决方案2】:

出于在采访中明确指出的原因,添加这种支持会增加大量额外的复杂性,但会带来非常小的额外好处。如果您知道如何设计和编写编译器,您可以(在其他一些论坛上)争论这是对还是错的程度,而不是它是否“愚蠢”或使用该语言的开发人员可能有多“有限”...... .

【讨论】:

  • 这次采访特别提到了我所描述的之外的一个特定实现,这就是我将他描述为有限的原因。总是有另一种方法来做某事......你怎么看不到这一点?
  • 我已经删除了违规部分。我希望,在未来,你可以把注意力集中在整个问题上,而不是一些小的主观部分。
  • @Mike,你应该重新阅读采访,在采访中,安德斯特别说,在他的回应中,“你真正要问的是,你能在约束方面说什么?......”他说,“从一无所有到大模式匹配是一个完整的连续体。我们认为说什么都太少了,大模式匹配变得非常复杂,所以我们介于两者之间。”
  • @Mike,这个论坛做出了明确而一致的尝试,使内容集中在客观、技术、实质性的主题上,所以我们对即使是轻微的违规行为也可能有点苛刻。它具有工作的主要好处。我见过的任何其他论坛都没有像现在这样专业,没有激烈的争论和主观的争论。缺点?那些脸皮薄,并且有违反这些理想的倾向的人可能会有点被冒犯。适应,你会发现这个论坛对你的工具包很有价值......
【解决方案3】:

为什么不简单地将泛型限制为类型列表?

因为那时它不是通用。泛型作为一个整体扩展了类型系统的表现力;它们并非旨在成为一种类似于 C++ 模板的廉价搜索和替换机制。

是否有任何明显的原因说明为什么无法实施?

我否认问题的前提。如果我们想违背泛型的基本设计原则,它可以实现。哎呀,考虑到时间和预算,我敢肯定,我可以在不到一个月的时间内实施它。不过,我还有其他优先事项。

这太愚蠢了。

好吧,当我周一见到安德斯时,我一定会告诉他,互联网上的 Mike K 认为他的想法很愚蠢。

他甚至建议这样做的事实表明 C# 开发人员是多么有限。

确实,我很清楚我的个人局限性。关于编程语言的设计和实现,我还有很多东西要学。

我还注意到,我们还受到预算、我们无法控制的市场力量以及许多其他因素的限制。

最后,让我借此机会指出,对能够回答您问题的人进行个人侮辱与您的问题得到回答的目标背道而驰。如果您对此感兴趣主题,您可以考虑阅读我关于该主题的短文:

http://blogs.msdn.com/ericlippert/archive/2008/02/20/how-to-not-get-a-question-answered.aspx

【讨论】:

  • 具有讽刺意味的是,几天前我正在与 Anders 就这个话题进行对话。泛化算术问题是一个有趣的问题,目前还不清楚解决它的最佳方法是什么,或者我们是否应该将有限的资源用于解决它而不是更重要的事情。
  • Eric:我想真正的问题是,为什么类型系统不能更好地包含本机值类型,至少对于泛型而言?恕我直言,这才是沮丧的真正根源。很难理解我们如何在 .NET 中拥有所有其他极其复杂的复杂类型和继承的东西,但是像 (Integer-->WholeNumbers-->PreciseNumbers-->Numbers) 这样的简单概念可以追溯到基础OO(以及泛型)不能包括在内吗?我已经厌倦了为 .NET 中的每种数字数据类型实现自己的复杂/向量/矩阵/等数学。
  • @RBarryYoung 如果您编写如下方法 T One(U a, V b) { return a + b;但手动为 T、U 和 V 插入 int、double、byte、long、ulong 等(在某些情况下使用相同的)。处理编译器错误和警告后,请查看反射器中的反编译代码。请注意如何没有函数调用(大多数通用相关行为的当前“构建块”)发生。确实请注意,实际上生成的 IL 几乎没有共性。尽管我很喜欢通用算术,但我承认生成通用机制是困难
  • 然而,从 1964 年开始,每一个 BASIC 编译器都能够正确地将多态算术运算符编译为机器指令,而无需依赖生成函数调用。我猜今天的编译器技术不像 1964 年那么先进?或者也许你的描述是一个红鲱鱼?
  • 本机值类型 .NET 类型系统的一等成员。它们继承自 System.ValueType,后者继承自 System.Object。现在,也许这个继承层次并没有成功地模拟数字你想要的方式。不幸的是,我现在对此无能为力。不过幸运的是:微软在了解科学和金融计算社区的需求方面投入了越来越多的资金。希望在未来我们能有更多的工具来服务于这个细分市场。
【解决方案4】:

我认为您正在寻找 OOP 中函数式编程语言的功能。如果是这种情况,请使用 FP。

例如,在 Scala 中,您可以替换运算符,因此现在它可以添加或乘以您的矩阵。

在各种语言中都是这种情况,但不是所有 OOP 语言。

当如何加法或乘法并不明显时,为什么泛型能够进行加法?例如,如果我有一类对数,那么乘法只是将数字相加,但是,编译器怎么知道呢?

在 C# 中,您可以进行运算符重载,这应该可以解决您抱怨的问题: http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx

C# 团队决定如何进行泛型,它不应该像我上面的示例所示那样处理数学,但他们确实允许你帮助编译器知道如何进行数学运算,所以责备他们因为不先征求他们的意见是非常冒险的,因为已经做出决定,仿制药就在原样。我相信它现在不会改变。

【讨论】:

  • 你用过c++模板吗?他们使这很容易。这不是命令域的问题,而是设计决策的缺陷。
  • @EdS。问题是关于 C#,这就是我这样回答的原因。这是 C# 和模板之间的比较,因为您是正确的模板更强大:msdn.microsoft.com/en-us/library/c6cyy67b.aspx
【解决方案5】:

我建议(请原谅我有限的知识,如果这听起来对任何人来说都是迟钝的)使用各自的关键字来实现模板和通用功能。在阅读了所有帖子(是的所有帖子)之后,我不得不说我同意这两种观点:泛型绝不应该是“像 C++ 模板那样廉价的搜索和替换机制”,但是当你必须实现相同的时候2+ 类型的函数变得非常烦人:P

也许可以使用 IArithmetic 接口说明需要实现的运算符来使约束更严格?

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2013-11-27
    • 1970-01-01
    相关资源
    最近更新 更多