【问题标题】: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>。

标签: c# .net operators


【解决方案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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2017-11-18
      • 2018-03-27
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多