【问题标题】:What's the false operator in C# good for?C# 中的 false 运算符有什么用?
【发布时间】:2008-08-28 20:06:01
【问题描述】:

C#中有两个奇怪的运算符:

如果我理解这一权利,这些运算符可用于我想使用的类型而不是布尔表达式,并且我不想提供到布尔的隐式转换。

假设我有以下课程:

    public class MyType
    {
        public readonly int Value;

        public MyType(int value)
        {
            Value = value;
        }

        public static bool operator true (MyType mt)
        {
            return  mt.Value > 0;
        }

        public static bool operator false (MyType mt)
        {
            return  mt.Value < 0;
        }

    }

所以我可以写如下代码:

    MyType mTrue = new MyType(100);
    MyType mFalse = new MyType(-100);
    MyType mDontKnow = new MyType(0);

    if (mTrue)
    {
         // Do something.
    }

    while (mFalse)
    {
        // Do something else.
    }

    do
    {
        // Another code comes here.
    } while (mDontKnow)

但是,对于上面的所有示例,仅执行 true 运算符。那么 C# 中的 false 运算符有什么用呢?

注意:更多示例可以在hereherehere 找到。

【问题讨论】:

标签: c# .net syntax


【解决方案1】:

您可以使用它来覆盖 &amp;&amp;|| 运算符。

&amp;&amp;|| 运算符不能被覆盖,但如果你覆盖 |&amp;truefalse,编译器将调用 |&amp; 当你写 ||&amp;&amp;

例如,看看这段代码(来自http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - 我发现了这个技巧;archived version@BiggsTRC):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

这显然是一个副作用,而不是它的预期使用方式,但它很有用。

【讨论】:

  • 您的链接是 404。不确定您要如何编辑它,所以我保留了它。
  • 我用存档副本更新了 URL,以便仍然可以阅读。
【解决方案2】:

Shog9 和 Nir: 谢谢你的回答。这些答案将我指向Steve Eichert article,并将我指向msdn

操作 x && y 被评估为 T.false(x) ? x : T.&(x, y),其中 T.false(x) 是对 T 中声明的运算符 false 的调用,而 T.&(x, y) 是对选定运算符 & 的调用。换句话说,首先评估 x 并在结果上调用运算符 false 以确定 x 是否肯定为假。然后,如果 x 肯定为假,则操作的结果是先前为 x 计算的值。否则,对 y 求值,并对先前为 x 计算的值和为 y 计算的值调用选定的运算符 & 以产生操作结果。

【讨论】:

  • 我想知道他们为什么不选择使用(!T.true(x)) ? x : T.&amp;(x, y) 逻辑。
【解决方案3】:

您链接到http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx 的页面说明了它们的用途,这是在引入可空值类型之前处理可空布尔值的一种方式。

我猜现在它们适用于与 ArrayList 相同的东西 - 即绝对没有。

【讨论】:

    【解决方案4】:

    AFAIK,它将用于测试是否为 false,例如当 &amp;&amp; 运算符发挥作用时。请记住,&& 短路,所以在表达式中

    if ( mFalse && mTrue) 
    {
       // ... something
    }
    

    mFalse.false() 被调用,在返回 true 时,表达式被简化为对 'mFalse.true()' 的调用(然后应该返回 false,否则事情会变得很奇怪)。

    请注意,您必须实现&amp; 运算符才能编译该表达式,因为如果mFalse.false() 返回false,则使用它。

    【讨论】:

      【解决方案5】:

      从您链接到它的 MSDN 文章中可以看出,在将 Nullable(即 int?、bool? 等)类型引入 C#2 语言之前,提供了可以为空的布尔类型。因此,您将存储一个内部值,指示该值是 true 还是 false 或 null,即在您的示例中,>0 表示 true,

      与 SQL 相比,想象一个表 Table 有 3 行的值 Foo 设置为 true,3 行的值 Foo 设置为 false,3 行的值 Foo 设置为 null。

      SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
      6
      

      为了计算所有行,您必须执行以下操作:-

      SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
      9
      

      这种“IS NULL”语法在您的类中将具有等效代码为 .IsNull()。

      LINQ 使与 C# 的比较更加清晰:-

      int totalCount = (from s in MyTypeEnumerable
                       where s || !s
                       select s).Count();
      

      假设 MyTypeEnumberable 与数据库的内容完全相同,即 3 个值等于 true,3 个值等于 false,3 个值等于 null。在这种情况下,totalCount 将评估为 6。但是,如果我们将代码重写为:-

      int totalCount = (from s in MyTypeEnumerable
                       where s || !s || s.IsNull()
                       select s).Count();
      

      然后 totalCount 将计算为 9。

      链接的 MSDN 文章中关于 false 运算符的 DBNull 示例演示了 BCL 中具有这种确切行为的类。

      实际上的结论是你不应该使用它,除非你完全确定你想要这种类型的行为,最好只使用更简单的可空语法!

      更新:我刚刚注意到您需要手动覆盖逻辑运算符!,||和 && 使其正常工作。我相信错误运算符会输入这些逻辑运算符,即表示真、假或“否则”。正如另一条评论中指出的那样!x 不会立即起作用;你必须超载!奇怪!

      【讨论】:

        猜你喜欢
        • 2010-11-21
        • 2011-03-29
        • 1970-01-01
        • 2010-10-24
        • 2021-11-08
        • 1970-01-01
        • 2010-12-11
        相关资源
        最近更新 更多