为什么不能将运算符作为参数传递?

时间:2013-06-11 04:51:29

标签: c# .net operators

我试图编写一个有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不允许操作符作为参数传递给方法? 设计背后的想法是什么?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

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;
}

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

相关问题