为啥不能将运算符作为参数传递? [关闭]

Posted

技术标签:

【中文标题】为啥不能将运算符作为参数传递? [关闭]【英文标题】:Why is it not possible to pass an operator as an argument? [closed]为什么不能将运算符作为参数传递? [关闭] 【发布时间】:2013-06-06 20:45:57 【问题描述】:

我正在尝试编写一个具有 LINQ 查询的方法。

所以这个方法:

DoSomething(Operator operator, string name)

  // if operator is ==
  // use == as comparison
  // if operator is !=
  // use != as comparison

  // pseudo query
  var result = from rec in collection
               where rec.name operator name
               select rec;
 

我知道这可以使用委托、Func 和 Action 来完成,它的解释非常优雅 here。

但我想知道的是为什么一个方法只需要一个类型? 为什么 CLR 不允许将运算符作为参数传递给方法? 设计背后的想法是什么?

【问题讨论】:

您的伪代码实际上并没有使用您在任何地方传递的运算符。 可能是因为功能不是worth more than 100 points 我想问一下,你为什么要实现这个功能? 在这个具体的例子中,你不应该关心你正在应用某种二元运算,而应该简单地接受一个谓词,比如Predicate<string>Func<string, bool> 【参考方案1】:

CLR 与此无关。运算符仅存在于语言级别,并且在编译为 IL 时归结为静态方法(可能带有一些标志)。这些静态方法使用像op_Addition 这样的标准名称,但这只是为了简化支持运算符重载的语言之间的兼容性。例如,实现operator == 的静态方法完全可以作为Func<T, T, bool> 传入。

至于为什么 C# 明确不允许将运算符解释为方法组并转换为匹配的委托类型,我可以看到几个原因。首先,这更像是一种函数式编程,而 C# 的设计是为了保持熟悉的 OOP/Java-ish 类型的结构(尽管从那时起他们已经对此进行了扩展)。其次,语法是什么? DoSomething(==, "foo") 可能会在语法中产生很多歧义,而 C++ish DoSomething(operator==, "foo") 开始变得非常复杂。最后,这可能是 C# 程序员不会经常使用甚至不知道的东西,请记住 all features start at -100 points。

【讨论】:

【参考方案2】:

我想说的很简单,因为这不是操作员的处理方式。考虑这样一个类:

public class A

    public int Prop  get; set; 

现在考虑这段代码:

var a1 = new A()  Prop = 1 ;
var a2 = new A()  Prop = 2 ;

目前我需要这样做:

if (a1.Prop == a2.Prop)

这会起作用,但如果我能做到这一点呢:

if (a1 == a2)

这确实意味着上述内容。这就是运营商所做的。这就是为什么您不能将它们作为参数传递的原因。事实上,我刚刚展示的代码比你提供的更简洁。为什么不像这样重载运算符:

public static bool operator ==(A a1, A a2)

    return a1.Prop == a2.Prop;

或者在您的情况下,在重载中运行适当的查询。就这么简单!

【讨论】:

以上是关于为啥不能将运算符作为参数传递? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将常量数组作为参数传递?

为啥我们不能将字符串作为模板参数传递?

为啥我们将视图和上下文对象作为函数中的参数传递,API 22 [关闭]

C语言中,数组名作为函数参数,属于啥传递,为啥?

为啥将函数作为函数的参数传递?

为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?