为啥不能将运算符作为参数传递? [关闭]
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;
或者在您的情况下,在重载中运行适当的查询。就这么简单!
【讨论】:
以上是关于为啥不能将运算符作为参数传递? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章