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

如果我理解正确,这些运算符可以用在我想使用而不是布尔表达式的类型中,并且我不想提供到 bool 的隐式转换。

假设我有以下课程:

    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 运算符有什么用呢?

笔记:可以找到更多示例 这里, 这里这里.

有帮助吗?

解决方案

您可以使用它来覆盖 &&|| 运营商。

&&|| 运算符不能被覆盖,但如果您覆盖 |, &, truefalse 以编译器调用的正确方式 |& 当你写的时候 ||&&.

例如,看看这段代码(来自 http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - 我从哪里知道这个技巧的; 存档版本 通过@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;
}

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

其他提示

Shog9 和 Nir:感谢您的回答。这些答案向我指出 史蒂夫·艾克特文章 它向我指出 msdn:

运算 x && y 的计算结果为 T.false(x) ?X :T.&(x, y),其中 T.false(x) 是对 T 中声明的运算符 false 的调用,T.&(x, y) 是对所选运算符 & 的调用。换句话说,首先计算 x,并对结果调用 false 运算符以确定 x 是否确实为 false。然后,如果 x 肯定为假,则运算结果就是先前为 x 计算的值。否则,计算 y,并对先前为 x 计算的值和为 y 计算的值调用所选运算符 & 以产生运算结果。

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

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

AFAIK,它将用于错误测试,例如当 && 运算符开始发挥作用。请记住,&& 短路,因此在表达式中

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

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

请注意,您必须实施 & 运算符以便编译该表达式,因为它使用了 if mFalse.false() 回报 false.

从您链接到的 MSDN 文章看来,提供它是为了允许在 Nullable 之前使用可空布尔类型(即int?、bool? 等)类型被引入到 C#2 语言中。因此,您将存储一个内部值,指示该值是真、假还是空,即在您的示例中,>0 表示 true,<0 表示 false,==0 表示 null,然后您将获得 SQL 样式的 null 语义。您还必须实现 .IsNull 方法或属性,以便可以显式检查空性。

与 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。

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

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

更新: 我只是注意到您需要手动覆盖逻辑运算符!和&&使这项工作正常。我相信错误运算符会输入到这些逻辑运算符中,即表明真实、虚假或“其他”。正如另一条评论中所述 !x 不会立即起作用;你必须超载!奇怪!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top