我试图编写一个有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不允许操作符作为参数传递给方法? 设计背后的想法是什么?
答案 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;
}
或者在您的情况下,在重载中运行适当的查询。就这么简单!