为什么不能将操作符作为参数传递

本文关键字:参数传递 操作符 不能 为什么 | 更新日期: 2023-09-27 18:18:00

我正在尝试编写一个具有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来完成,这里已经解释得很清楚了。

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

为什么不能将操作符作为参数传递

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

至于为什么c#不允许将操作符解释为方法组并转换为匹配的委托类型,我可以看到几个原因。首先,这更像是一种函数式编程,而c#的设计是保持熟悉的OOP/java类型的结构(尽管从那时起他们已经扩展了)。第二,语法是什么?DoSomething(==, "foo")可能会在语法中产生许多歧义,而c++风格的DoSomething(operator==, "foo")开始变得非常不必要的复杂。最后,这可能是c#程序员不会经常使用或甚至不知道的东西,请记住所有功能都是从-100点开始的。

我会说相当简单,因为操作符不是这样处理的。考虑这样一个类:

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

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