什么时候重载的false运算符会被执行,它有什么用呢?

com*_*cme 10 c# operator-overloading

我一直在寻找实际工作代码,其中重载false运算符实际上被执行.

这个问题(C#中的false运算符有什么用?)有点相同,但是接受的答案链接到一个返回404错误的url.我还看过运营商如何重载真假工作?和其他一些问题.

我几乎在所有答案中都发现,false只有当你使用短路时才能执行x && y.这被评估为T.false(x) ? x : T.&(x, y).

好的,所以我有以下代码.在struct包含int和认为自己真要是int是大于零:

public struct MyStruct {
    private int _i;

    public MyStruct(int i) {
        _i = i;
    }

    public static bool operator true(MyStruct ms) {
        return ms._i > 0;
    }

    public static bool operator false(MyStruct ms) {
        return ms._i <= 0;
    }

    public override string ToString() {
        return this._i.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我希望以下程序将执行并使用重载false运算符.

class Program {
    private static void Main() {
        MyStruct b1 = new MyStruct(1); // to be considered true
        MyStruct b2 = new MyStruct(-1); // to be considered false

        Console.WriteLine(b1 && b2);
        Console.WriteLine(b2 && b1);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,它甚至没有编译.它说它不能将运算符'&&'应用于'MyStruct'和'MyStruct'类型的操作数.

我知道我可以实现&运算符的重载.所以,让我们这样做.在& 必须返回一个MyStruct,所以我不能让它返回bool.

public static MyStruct operator &(MyStruct lhs, MyStruct rhs) {
    return new MyStruct(lhs._i & rhs._i);
}
Run Code Online (Sandbox Code Playgroud)

现在代码编译了.它的输出是1-1.所以结果与之b1 && b2不一样b2 && b1.

如果我调试代码,我看到b1 && b2首先执行false运算符on b1,返回false.然后它&在b1和b2上执行运算符,它执行按位,并在1和-1上执行,结果为1.所以它确实首先检查b1是否为假.

第二个表达式,b2 && b1首先执行false运算符on b2,返回true.结合我使用短路的事实,它没有做任何事情,b1只是打印出的值b2.

所以是的,false操作员在您使用短路时执行.但是,它不会在第二个参数上执行trueor false运算符,而是&在操作数上执行重载运算符.

什么时候这可能有用吗?或者我如何制作我的类型以便它可以检查这两个变量是否都是真的?

IAm*_*rey 5

您提到的URL为404的内容可以在这里找到:

http://web.archive.org/web/20080613013350/http://www.ayende.com/Blog/archive/2006/08/04/7381.aspx

作者所指的文章在这里:

http://web.archive.org/web/20081120013852/http://steve.emxsoftware.com/NET/Overloading+the++and++operators

为了避免再次出现同样的问题,以下是文章的重点:

几个月前,我发布了关于我们的查询API以及它如何工作的解释.我们的查询API允许我们使用强类型C#语法表达我们的查询:

List<Customer> customers = repository.FindAll(Customer.Columns.Age == 20 & Customer.Columns.Name == “foo”);
Run Code Online (Sandbox Code Playgroud)

我在之前的帖子中指出的一件事是我无法重载&&和|| 操作员直接因为框架不允许这样的疯狂......至少不是直接的.

特别是,不能重载成员访问,方法调用或=,&&,||,?:,checked,unchecked,new,typeof,as和is运算符. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_7_2_2.asp

在过去的一个月里,我对这个主题进行了一些调查,看看是否以及如何获得&&和|| 表现我想要的方式.今天晚上我遇到了MSDN上的条件逻辑运算符页面,它给了我正在寻找的答案:

操作x && y被评估为T.false(x)?x:T.&(x,y),其中T.false(x)是在T中声明的运算符false的调用,并且T.&(x,y)是所选运算符&的调用.换句话说,首先计算x并在结果上调用operator false以确定x是否肯定为false.然后,如果x肯定是假的,则操作的结果是先前为x计算的值.否则,计算y,并且对先前为x计算的值和为y计算的值调用所选运算符&以生成操作的结果.操作x || y被评估为T.true(x)?x:T.|(x,y),其中T.true(x)是在T中声明的运算符true的调用,而T. |(x,y)是所选运算符|的调用.换句话说,首先计算x并在结果上调用operator true以确定x是否肯定为真.然后,如果x绝对为真,则操作的结果是先前为x计算的值.否则,将评估y,并选择运算符| 在先前为x计算的值和为y计算的值上调用,以生成操作的结果.因为我们已经有&和| 运算符到位只是一个重载真假操作符的问题都返回false.这导致&和| 操作员总是被调用,这反过来会导致两个标准对象变成AndCriteria/OrCriteria!

所以现在我们可以使用&&和||表达我们的标准表达式 我们习以为常的语法.

repository.FindAll(Customer.Columns.Age == 20 && Customer.Columns.Name == “foo”);

repository.FindAll(Customer.Columns.FirstName == “Foo” || Customer.Columns.LastName == “Bar”);
Run Code Online (Sandbox Code Playgroud)

相关的运算符重载如下所示.

public static bool operator true(Criteria<T> criteria) {
   return false;
}

public static bool operator false(Criteria<T> criteria) {
   return false;
}

public static Criteria<T> operator &(Criteria<T> lhs, Criteria<T> rhs) {
   return new AndCriteria<T>(lhs, rhs);
}

public static Criteria<T> operator |(Criteria<T> lhs, Criteria<T> rhs) {
   return new OrCriteria<T>(lhs, rhs);
}
Run Code Online (Sandbox Code Playgroud)


Bra*_*AGr 4

编辑-

阅读链接的文章,我能够得到以下同时使用 true 和 false 运算符的输出:

op false on 1
op & on 1 -1
op true on 1
op true on -1
FALSE
op false on -1
op true on -1
FALSE
op true on 1
op true on 1
TRUE
op true on -1
op & on -1 1
op true on -1
op true on 1
TRUE
Run Code Online (Sandbox Code Playgroud)

用代码:

class Program
{
    static void Main(string[] args)
    {
        MyStruct b1 = new MyStruct(1); // to be considered true
        MyStruct b2 = new MyStruct(-1); // to be considered false

        Console.WriteLine((b1 && b2) ? "TRUE" : "FALSE");
        Console.WriteLine((b2 && b1) ? "TRUE" : "FALSE");

        Console.WriteLine((b1 || b2) ? "TRUE" : "FALSE");
        Console.WriteLine((b2 || b1) ? "TRUE" : "FALSE");

        Console.ReadLine();
    }
}

public struct MyStruct
{
    private int _i;

    public MyStruct(int i)
    {
        _i = i;
    }

    public static bool operator true(MyStruct ms)
    {
        Console.WriteLine("op true on {0}", ms);
        return ms._i > 0;
    }

    public static bool operator false(MyStruct ms)
    {
        Console.WriteLine("op false on {0}", ms);
        return ms._i <= 0;
    }

    public static MyStruct operator &(MyStruct lhs, MyStruct rhs)
    {
        Console.WriteLine("op & on {0} {1}", lhs, rhs);

        if (lhs)
        {
            return rhs;
        }
        else
        {
            return new MyStruct(-1); //-1 is false
        }
    }

    public static MyStruct operator |(MyStruct lhs, MyStruct rhs)
    {
        Console.WriteLine("op & on {0} {1}", lhs, rhs);

        if (lhs)
        {
            return lhs;
        }
        else
        {
            return rhs;
        }
    }

    public override string ToString()
    {
        return this._i.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

当你说第一个代码无法编译时,我不确定你的意思是什么,尽管它没有使用运算符 true/false,但我在 2010 Express 中运行了以下代码并得到了输出:

op bool on 1
op bool on -1
False
op bool on -1
False
op bool on -1
op bool on 1
True
op bool on 1
True
Run Code Online (Sandbox Code Playgroud)

代码:

class Program
{
    static void Main(string[] args)
    {
        MyStruct b1 = new MyStruct(1); // to be considered true
        MyStruct b2 = new MyStruct(-1); // to be considered false

        Console.WriteLine(b1 && b2);
        Console.WriteLine(b2 && b1);

        Console.WriteLine(b2 || b1);
        Console.WriteLine(b1 || b2);

        Console.ReadLine();
    }
}

public struct MyStruct
{
    private int _i;

    public MyStruct(int i)
    {
        _i = i;
    }

    public static bool operator true(MyStruct ms)
    {
        Console.WriteLine("op true on {0}", ms);
        return ms._i > 0;
    }

    public static bool operator false(MyStruct ms)
    {
        Console.WriteLine("op false on {0}", ms);
        return ms._i <= 0;
    }

    public static implicit operator bool(MyStruct ms)
    {
        Console.WriteLine("op bool on {0}", ms);
        return ms._i > 0;
    }

    public override string ToString()
    {
        return this._i.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)