首页 > 编程语言 >C#中的 `true` 和 `false` 运算符

C#中的 `true` 和 `false` 运算符

时间:2022-10-27 12:00:46浏览次数:85  
标签:BoolTest C# 运算符 call false true op

C#中的truefalse运算符

基础用法

我们先定义一个示例用的类

public class BoolTest
{
    public int X { get; set; }
    public BoolTest(int x) { X = x; }
    public static bool operator true(BoolTest test)
    {
        Console.WriteLine("call op_true");
        return test.X > 0;
    }
    public static bool operator false(BoolTest test)
    {
        Console.WriteLine("call op_false");
        return test.X < 0;
    }
}

定义了truefalse运算符后,类可以在可以用于ifdowhilefor语句以及条件表达式中的控制表达式。

if (new BoolTest(1))
    ; // 会有空语句警告,请忽视
if (new BoolTest(-1))
    ;
// output:
// call op_true
// call op_true

可以看到,我们只调用了true运算符,那么false运算符用在哪里呢

定义||&&运算符

更确切地说,false运算符是用于定义||运算符的

在此之前,我默认你已经知道逻辑运算符的短路运算

C#不能直接定义||&&运算符,而是通过定义|true来获得||,定义&false来得到&&,其原因就是为了支持短路运算。

现在更新我们的类

public class BoolTest
{
    public int X { get; set; }
    public BoolTest(int x) { X = x; }

    public static bool operator true(BoolTest test)
    {
        Console.WriteLine("call op_true");
        return test.X > 0;
    }
    public static bool operator false(BoolTest test)
    {
        Console.WriteLine("call op_false");
        return test.X < 0;
    }

    public static BoolTest operator |(BoolTest left, BoolTest right)
    {
        return new BoolTest(Math.Max(left.X, right.X));
    }
    public static BoolTest operator &(BoolTest left, BoolTest right)
    {
        return new BoolTest(Math.Min(left.X, right.X));
    }
    // 这两个运算符必须返回BoolTest类型(准确的说是返回和参数相同的类型)
}
BoolTest p = new BoolTest(1);
BoolTest n = new BoolTest(-1);

if (p || n)
    WriteLine("p || n");
    /*
    call op_true
    call op_true 调用了两次true()
    p || n
    */
if (p && n)
    WriteLine("p && b");
    /*
    call op_false 使用了false()来作短路判断
    call op_true 此时p是True,调用&()生成新的BoolTest,再对新的BoolTest调用true()
    */
if (n || p)
    WriteLine("n || p");
    /*
    call op_true 对n
    call op_true 对(n | p)
    n || p
    */
if (n && p)
    WriteLine("n && p");
    /*
    call op_false 对n
    call op_true 对n
    */

结论就是
a || b等价于operator_true(operator_true(a) ? a : (a | b))
a && b等价于operator_true(operator_false(a) ? a : (a & b))

注意:最终的真或假还是交由true运算符判断false运算符只在短路中用到

truefalse运算符还用于支持三元逻辑值(True, False, Null),不过现在有bool?类型了

这个链接是三元逻辑值的示例类 struct DBBool

标签:BoolTest,C#,运算符,call,false,true,op
From: https://www.cnblogs.com/violeshnv/p/16831742.html

相关文章

  • C#笔记(输入输出、格式化、注释)
    输入输出ConsoleKeyInfoc;do{c=Console.ReadKey();//读取按键}while(c.Key!=ConsoleKey.Escape);//等待输入Esc键strings=Console.ReadLine();i......
  • csharp-webuploader+csharp如何实现分片+断点续传
    ​文件夹数据库处理逻辑public class DbFolder{    JSONObjectroot;       public DbFolder()    {        this.root= new JSONOb......
  • C语言结构体中的零长数组
    C语言结构体中的零长数组实例structA{intlen;intvar[0];};structB{intlen;int*var;}其中,结构体A使用了零长数组,结构体B用了指针。为......
  • fs01 FreeSWITCH中APP和API
    PART1APP和API的区别 简单来说,一个APP是一个程序,它作为一个Channel一端与另一端的UA进行通信,相当于它工作在Channel内部;而一个API则是独立于一个Channel之外的,它只能通......
  • C语言的单引号问题
    C语言的单引号问题单引号的原理C语言的单引号实际上时将''内的字符转化为ASCII码对应的整型值,并且在存储时占据一个字节,即sizeof(char)//第一个例子intmain(){......
  • rancher 部署k8s
    yuminstall-yyum-utils  device-mapper-persistent-data  lvm2curl-o/etc/yum.repos.d/CentOS-Base.repohttp://mirrors.aliyun.com/repo/Centos-7.repoyum-co......
  • C#在调用UI刷新时启用了不同的线程,导致数据异常的解决方案
    将原先的刷新函数封装如下原先的调用方式publicvoidRefreshGrid(){System.Diagnostics.Debug.WriteLine("CurrentThreadID:"+System.Threadi......
  • Scrum五大会议要怎么开?
    在Scrum框架中,我们对Scrum的五个会议一定都不陌生,但如何组织这五个会议,才能让Scrum团队真正积极、主动地参与进项目管理中呢?在Scrum框架中,我们对Scrum的五个会议一定......
  • CSS注册页面案例
    CSS注册页面案例使用CSS完成效果图片  代码实现: <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><style>......
  • TCP 端来链接为什么一定要等2MSL
    我们知道tcp传输中需要三次握手和四次挥手2MSL发生在挥手阶段原因保证可靠的TCP通讯安全的断开保证旧的的消息在网络消失安全断开我们知道一个IP包最大的声明......