C#基础语法 — (5)操作符详解


一、操作符概览

在这里插入图片描述

  • 操作符(Operator)也译为“运算符”
  • 操作符是用来操作数据的,被操作符操作的数据称为操作数(Operand)

二、操作符的本质

  • 操作符的本质是函数(即算法)的“简记法”
    • 假如没有发明“+”,只有 Add 函数,算式 3+4+5将可以写成 Add(Add(3,4),5)
    • 假如没有发明“*”,只有 Mul 函数,那么算式 3+4*5 只能写成 Add(3,Mul(4,5))
  • 操作符不能脱离与它关联的数据类型
    • 可以说操作符就是与固定数据类型相关联的一套基本算法的简记法
    • 示例:为自定义数据类型创建操作符

下例中的操作符+ 就是 GetMarry 方法的简记:

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person1 = new Person();
            Person person2 = new Person();
            person1.Name = "Deer";
            person2.Name = "Deer's wife";
            //List<Person> nation = Person.GetMarry(person1, person2);
            List<Person> nation = person1 + person2;
            foreach (var p in nation)
            {
                Console.WriteLine(p.Name);
            }
        }
    }

    class Person
    {
        public string Name;

        //public static List<Person> GetMarry(Person p1, Person p2)
        public static List<Person> operator +(Person p1, Person p2)//操作符+
        {
            List<Person> people = new List<Person>();
            people.Add(p1);
            people.Add(p2);
            for (int i = 0; i < 11; i++)
            {
                Person child = new Person();
                child.Name = p1.Name + "&" + p2.Name + "'s child";
                people.Add(child);
            }
            return people;
        }
    }
}

三、优先级与运算顺序

  • 操作符的优先级
    • 可以使用圆括号提高被括起来表达式的优先级
    • 圆括号可以嵌套
    • 不像数学里有方括号与花括号,在 C# 语言里面“[]”与“{}”有专门的用途
  • 同优先级操作符的运算顺序
  • 除了带有赋值功能的操作符,同优先级操作符都由左向右进行运算
  • 带有赋值功能的操作符的运算顺序是由右向左
  • 与数学运算不同,计算机语言的同优先级运算没有“结合率”
    • 3+4+5 只能理解为 Add(Add(3,4),5) 不能理解为 Add(3,Add(4,5))

同优先级操作符的运算顺序:

    class Program
    {
        static void Main(string[] args)
        {
            int x;
            x = 3 + 4 + 5;//"+"比"="优先级高,先算"+";两个"+"优先级一样,从左往右;最后赋给x
            Console.WriteLine(x);//x=12            
        }
    } 
        static void Main(string[] args)
        {
            int x = 100;
            int y = 200;
            int z = 300;

            x += y += z;//y=y+z;x=x+(y+z);

            Console.WriteLine(x);//600
            Console.WriteLine(y);//500
            Console.WriteLine(z);//300
        }
    }

四、各类操作符的示例

在这里插入图片描述

1.基本操作符

. 成员访问操作符

功能:
  1.访问外层名称空间中的子名称空间
  2.访问名称空间中的类型
  3.访问类型的静态成员
  4.访问对象中的实例成员

System.IO.File.Create("D:\\HelloWorld.txt");
      1  2    3

Form myForm = new Form();
myForm.Text = "Hello, World";
      4
myForm.ShowDialog();
      4

f(x) 方法调用操作符

  方法调用操作符就是方法后面的那对()
  f是function的缩写,()中的x指的是方法调用时的参数。

  方法名后面不一定要有()
  Action 是委托,委托在创建时只需要知道方法的名称,不调用方法,所以只会用到方法名(不加())。当然最终ac();也用到了方法调用操作符()。

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            Calculator c = new Calculator();

            double x = c.Add(3.0, 5.0);//调用Add方法
            Console.WriteLine(x);

            Action ac = new Action(c.PrintHello);//访问c.PrintHello这个成员,而不是调用PrintHello方法
            ac();//调用被ac管理的方法—PrintHello()
        }
    }

    class Calculator
    {
        public double Add(double a, double b)
        {
            return a + b;
        }

        public void PrintHello()
        {
            Console.WriteLine("Hello World");
        }
    }
}

a[x] 元素访问操作符

访问数组元素:

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] myArray = new int[10];//创建长度为10的数组
            Console.WriteLine(myArray[0]);

            int[] myArray1 = new int[] { 1, 2, 3, 4, 5 };//创建含有这几个元素的数组
            Console.WriteLine(myArray1[0]);

            int[] myArray2 = new int[3] { 1, 2, 3 };//创建数组
            Console.WriteLine(myArray2[0]);
        }
    }
}

访问字典中的元素:

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, Student> stuDic = new Dictionary<string, Student>();
            for (int i = 1; i < 101; i++)
            {
                Student stu = new Student();
                stu.Name = "s_" + i.ToString();
                stu.Score = 100 + i;
                stuDic.Add(stu.Name, stu);
            }

            //访问s_6的学生的成绩
            Student number6 = stuDic["s_6"];
            Console.WriteLine(number6.Score);
        }
    }

    class Student
    {
        public string Name;
        public int Score;
    }
}

x++ x-- 后置自增、自减操作符

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 100;
            x++;//x=x+1;
            Console.WriteLine(x);//x=101

            int y = 100;
            y--;//y=y-1;
            Console.WriteLine(y);//y=99

            int a = 100;
            int b = a++;//a=a+1;先赋值再自增
            Console.WriteLine(a);//101
            Console.WriteLine(b);//100        
        }
    }  
}

typeof 操作符

  查看类型的内部结构—检测类型元数据(Metadata)

    class Program
    {
        static void Main(string[] args)
        {
            //查看int类型的内部结构
            Type t = typeof(int);
            Console.WriteLine(t.Namespace);//名称空间:System
            Console.WriteLine(t.FullName);//全名:System.Int32
            Console.WriteLine(t.Name);//不带名称空间的名字:Int32

            //查看int的所有方法
            int c = t.GetMethods().Length;
            foreach (var mi in t.GetMethods())
            {
                Console.WriteLine(mi.Name);//方法的名字
            }
            Console.WriteLine(c);
        }
    } 

default 操作符

  获取一个类型的默认值

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            //结构体类型;值类型内存块都刷成0,值就是0
            int x = default(int);
            Console.WriteLine(x);//默认值0

            //引用类型;内存块都刷成0,值就是null
            Form myForm = default(Form);
            Console.WriteLine(myForm == null);//True            

            //枚举类型
            //枚举类型映射到整型上,默认枚举值是对应值为 0 的那个,可能是你手动指定的,也可能是系统默认赋值的。
            //这就牵扯到我们使用枚举时,要注意枚举中是否有对应 0 的;创建枚举类型时,最好有一个对应 0 的,以免他人查找我们枚举的 default 值时报错。
            Level level = default(Level);
            Console.WriteLine(level);
        }
    }

    //声明枚举类型
    enum Level
    {       
        Mid = 1,
        Low = 0,
        High = 2
    }
}

new 操作符

new当作操作符使用:

显式类型与隐式类型的变量

//显式类型的变量
int x;//在声明变量时,明显的告诉编译器变量的数据类型是什么

//隐式类型的变量
var x1 = 100;//在声明变量时,数据类型由编译器根据所赋的值来推断
Console.WriteLine(x1.GetType().Name);//Int32

在内存中创建类型实例,并立刻调用实例构造器
把实例的内存地址通过赋值操作符交给访问它的变量;通过变量来访问实例

//在内存中创建类型实例,并立刻调用实例构造器
//把实例的内存地址通过赋值操作符交给访问它的变量;通过变量来访问实例
var MyForm = new Form();
MyForm.Text = "Hello";
MyForm.ShowDialog();

new操作符还可以调用实例的初始化器

var MyForm = new Form() {Text="Hello"};//{}为实例的属性设置值          
MyForm.ShowDialog();
var MyForm = new Form() //{}初始化器中有多个属性
{
	Text = "Hello",
    FormBorderStyle = FormBorderStyle.SizableToolWindow
 };
MyForm.ShowDialog();
// new 一次性变量:利用实例的初始化器直接 new 对象后,马上执行方法,然后就不管它了,随着 GC 去处理它
new Form() {Text = "Hello"}.ShowDialog();

C#的语法糖衣,声明基本数据类型的变量时可以不需要new操作符

            //C#的语法糖衣,声明基本数据类型的变量时可以不需要new操作符           
            string name = "Tim";
            string name1 = new string(new char[] { 'T', 'i', 'm' });
            Console.WriteLine(name1);//Tim

            int[] myArray = new int[10];
            int[] myArray1 = { 1, 2, 3, 4 };

为匿名类型创建对象

        static void Main(string[] args)
        {
            //非匿名类型
            Form myForm = new Form() { Text = "Hello" };

            //为匿名类型创建实例,并用隐式类型变量来引用实例
            var person = new { Name = "Mr.Okay", Age = 34 };
            Console.WriteLine(person.Name);
            Console.WriteLine(person.Age);
            Console.WriteLine(person.GetType().Name);//<>f__AnonymousType0`2
        }

在这里插入图片描述

new 操作符会导致依赖紧耦合,可以通过依赖注入模式来将紧耦合变成相对松的耦合。

// new 操作符功能强大,但会造成依赖。创建实例后,Program类 就依赖到 Form类 上了,
// 一旦 Form类 运行出错,Program类 也会出问题。
// 通过设计模式中的依赖注入模式来将紧耦合变成相对松的耦合
    class Program
    {
        static void Main(string[] args)
        {           
            Form myForm = new Form() { Text = "Hello" };     
        }
    }

new当作关键字使用:

namespace CreateOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu.Report();
            CsStudent csStu = new CsStudent();
            csStu.Report();   
        }
    }

    class Student
    {
        public void Report()
        {
            Console.WriteLine("I'm a student!");
        }
    }

    class CsStudent:Student//继承自父类Student
    {
        //new修饰符;子类对父类方法进行隐藏
        new public void Report()
        {
            Console.WriteLine("I'm CS Student");
        }
    }
}

checked & unchecked 操作符

  检查一个值在内存中是否有溢出。
  checked 时,x+1 直接就溢出变成 0 了。

        static void Main(string[] args)
        {
            uint x = uint.MaxValue;
            Console.WriteLine(x);
            string binStr = Convert.ToString(x, 2);
            Console.WriteLine(binStr);

            uint y = x + 1;//溢出;超出了数据类型大小范围
            Console.WriteLine(y);//值为0            
        }

在这里插入图片描述

   使用checked操作符

    class Program
    {
        static void Main(string[] args)
        {
            uint x = uint.MaxValue;
            Console.WriteLine(x);
            string binStr = Convert.ToString(x, 2);
            Console.WriteLine(binStr);            

            try
            {
                uint y = checked(x + 1);//溢出;超出了数据类型范围
                Console.WriteLine(y);
            }
            catch (OverflowException ex)
            {

                Console.WriteLine("There's overflow!");
            }
        }
    }

在这里插入图片描述

  使用unchecked操作符

try
{
    // C# 默认采用的就是 unchecked 模式
    uint y = unchecked(x + 1);
    Console.WriteLine(y);
}
catch (OverflowException ex)
{
    Console.WriteLine("There's overflow!");
}

  checked 与 unchecked 作为关键字

    class Program
    {
        static void Main(string[] args)
        {
            uint x = uint.MaxValue;
            Console.WriteLine(x);
            string binStr = Convert.ToString(x, 2);
            Console.WriteLine(binStr);

            checked //checked关键字
            {
                try
                {
                    uint y = x + 1;//溢出;超出了数据类型范围
                    Console.WriteLine(y);
                }
                catch (OverflowException ex)
                {

                    Console.WriteLine("There's overflow!");
                }
            }            
        }
    }

delegate 操作符

  现在常见的是把 delegate 当做委托关键字使用。
  delegate 也可以作为操作符使用,但由于 Lambda 表达式的流行,delegate 作为操作符的场景愈发少见(被 Lambda 替代,已经过时)。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // 方法封装提高了复用性,但如果我这个方法在别的地方不太可能用到,我就可以使用匿名方法
        // 下面就是使用 delegate 来声明匿名方法
        //this.myButton.Click += delegate (object sender, RoutedEventArgs e)
        //{
        //    this.myTextBox.Text = "Hello, World!";
        //}; 

        // 现在推荐使用的是 Lambda 表达式
        this.myButton.Click += (sender, e) =>
        {
            this.myTextBox.Text = "Hello, World!";
        };
    }

    // 非匿名方法
    //private void MyButton_Click(object sender, RoutedEventArgs e)
    //{
    //    throw new NotImplementedException();
    //}
}

sizeof 操作符

  sizeof用于获取对象在内存中所占字节数。
注意:
  1.默认情况下,sizeof 只能用于获取基本数据类型的实例在内存中的字节数(string、object不行,因为只能获取结构体类型的实例在内存中的字节数)
  2.非默认情况下,可以使用 sizeof 获取自定义结构体类型的实例在内存中所占的字节数,但需要把它放在不安全的上下文中。

  需要在“项目属性”里面开启“允许不安全代码”。在这里插入图片描述

namespace SizeofSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //默认情况下
            int x = sizeof(int);
            Console.WriteLine(x);//4个字节

            int x1 = sizeof(long);
            Console.WriteLine(x1);//8个字节

            int x2 = sizeof(double);
            Console.WriteLine(x2);//8个字节

            int x3 = sizeof(decimal);
            Console.WriteLine(x3);//16个字节

            //非默认情况下
            unsafe
            {
                int y = sizeof(Student);
                Console.WriteLine(y);//16个字节
            }

        }
    }
 
    struct Student
    {
        int ID;
        long Socre;
    }
}

-> 操作符

  -> 操作符也必须放在不安全的上下文中才能使用。
  C# 中指针操作、取地址操作、用指针访问成员的操作,只能用来操作结构体类型,不能用来操作引用类型。

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                Student stu;
                stu.ID = 1;
                stu.Score = 99;
                Student* pStu = &stu;
                pStu->Score = 100;//通过指针访问对象
                Console.WriteLine(stu.Score);
            }
        }
    }

    struct Student
    {
        public int ID;
        public long Score;
    }
}

2.一元操作符

&x*x 操作符

  也需要在不安全的上下文中。

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                Student stu;
                stu.ID = 1;
                stu.Score = 99;
                Student* pStu = &stu;//&-取地址操作符
                pStu->Score = 100;//通过指针访问对象
                (*pStu).Score = 1000;//*-取引用操作符
                Console.WriteLine(stu.Score);
            }
        }
    }

    struct Student
    {
        public int ID;
        public long Score;
    }
}

+ - 正负操作符 与 ~ 取反操作符

			int x = 100;
            int y = +x;
            Console.WriteLine(y);//100

            int x1 = 100;
            int y1 = -x1;
            Console.WriteLine(y1);//-100

            int x2 = 100;
            int y2 = -(-x2);
            Console.WriteLine(y2);//100

  正负操作符使用不当,可能导致溢出。
  -操作符 相当于是 按位取反再加一

			int x = int.MinValue;
            int y = checked(-x);//OverflowException
            Console.WriteLine(y);


			//相反数 = 按位取反再加一
            int a = 123;
            int b = -a;//a的相反数
            int c = ~a;//对a按位取反

            string aStr = Convert.ToString(a, 2).PadLeft(32, '0');//变量a的二进制形式
            string bStr = Convert.ToString(b, 2).PadLeft(32, '0');
            string cStr = Convert.ToString(c, 2).PadLeft(32, '0');
        
            Console.WriteLine("a的相反数:"+bStr+"\n");
            Console.WriteLine("a按位取反:"+cStr);//再加一 就等于 相反数

在这里插入图片描述

! 取非操作符

  只能用来操作 布尔类型 的值

  			bool b1 = true;
            bool b2 = !b1;

            Console.WriteLine(b2);//False

  取非操作符在实际中的应用

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {            
            Student stu = new Student(null);
            Console.WriteLine(stu);

            
        }
    }

    class Student
    {
        //自定义构造器
        public Student(string initName)
        {
            if (!string.IsNullOrEmpty(initName))//若字符串非空
            {
                this.Name = initName;
            }
            else
            {
                throw new ArgumentException("initName cannot be null or empty!");
            }            
        }

        public string Name;
    }
}

++x --x 前置自增自减操作符

  无论前置、后置,在实际工作中,尽量单独使用它们,不要把它们和别的语句混在一起,那样会降低可读性。

        static void Main(string[] args)
        {
            int x = 100;
            int y = x++;//先赋值再自增
            Console.WriteLine(x);//101
            Console.WriteLine(y);//100

            int x1 = 100;
            int y1 = ++x1;//先自增再赋值
            Console.WriteLine(x1);//101
            Console.WriteLine(y1);//101            
        }

(T)x 强制类型转换操作符

  • 隐式(implicit)类型转换
    • 不丢失精度的转换
    • 子类向父类的转换
    • 装箱
  • 显式(explicit)类型转换
    • 有可能丢失精度(甚至发生错误)的转换,即cast
    • 拆箱
    • 使用Convert类
    • ToString方法与各数据类型的Parse/TryParse方法
  • 自定义类型转换操作符

隐式类型转换

在这里插入图片描述

  不丢失精度的隐式类型转换

			int x = int.MaxValue;
            long y = x;//隐式类型转换 int → long
            Console.WriteLine(y);

  子类向父类的转换
(拿一个引用变量去访问它所引用着的实例的成员的时候;只能访问到变量的类型它所具有的成员。
而不是访问变量所引用的实例的类型)

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            Teacher t = new Teacher();
            Human h = t;//子类向父类的隐式类型转换
            //拿一个引用变量去访问它所引用着的实例的成员的时候;只能访问到变量的类型,它所具有的成员。
            //而不是访问变量所引用的实例的类型
            h.Eat(); //只有Eat()和Think()方法

            //Animal a = h;
            //a.Eat();//只有Eat()方法
        }
    }

    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("Eating…");
        }
    }

    class Human : Animal//Human类继承自Animal类
    {
        public void Think()
        {
            Console.WriteLine("Who I am?");
        }
    }

    class Teacher : Human//Teacher了继承自Human类
    {
        public void Teach()
        {
            Console.WriteLine("I teach programming.");
        }
    }
}

显式类型转换

在这里插入图片描述

  有可能丢失精度(甚至发生错误)的转换,即cast
  在对象、变量前面加一对()() 里面写上要转换的目标数据类型

			uint x = 65536;
            ushort y = (ushort)x;//uint强制转换为ushort
            Console.WriteLine(y);

  使用Convert类进行强制类型转换

			bool x = true;
            int y = Convert.ToInt32(x);//通过Convert类,将bool转换为int
            Console.WriteLine(y);//值为1

   把数值类型转换为字符串类型
  ①使用Convert类的ToString()方法
  ②调用数值数据的实例方法ToString()

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            double x = System.Convert.ToDouble(th1.Text);
            double y = System.Convert.ToDouble(th2.Text);
            double result = x + y;

            //this.th3.Text = System.Convert.ToString(result);//使用Convert类的ToString()方法

            this.th3.Text = result.ToString();//调用数值数据的实例方法ToString()            
        }

  数据类型的Parse/TryParse方法

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            double x = double.Parse(th1.Text);//Parse()只能解析格式正确的字符串数据类型           
            double y = double.Parse(th2.Text);
            double result = x + y;
           
            this.th3.Text = result.ToString();//调用数值数据的实例方法ToString()            
        }

类型转换操作符是方法的简记

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            Stone stone = new Stone();
            stone.Age = 5000;
            Monkey wukongSun = (Monkey)stone;//Stone显式类型转换为Monkey类型
            //Monkey wukongSun = stone;//隐式类型转换
            Console.WriteLine(wukongSun.Age);

        }
    }

    class Stone
    {
        public int Age;

		//public static implicit operator Monkey(Stone stone){…} //隐式类型转换
		//显式类型转换
        public static explicit operator Monkey(Stone stone)//Stone → Monkey 
        {
            Monkey m = new Monkey();
            m.Age = stone.Age / 500;
            return m;
        }
    }

    class Monkey
    {
        public int Age;
    }
}

3.乘法操作符

* 乘法操作符

  要注意“数值提升”。
  具体参见《C# 定义文档》7.8 算术运算符。

        static void Main(string[] args)
        {           
            var x = 3.0 * 4;//数值提升;int→double
            Console.WriteLine(x.GetType().FullName);//System.Double
            Console.WriteLine(x);//12
        }

/ 除法操作符

    class Program
    {
        static void Main(string[] args)
        {
            //整数的除法;(除数不能为0)
            int x = 5;
            int y = 4;
            int z = x / y;//整除
            Console.WriteLine(z);//值为1

            //浮点类型的除法;(正数/0 = ∞ ;负数/0 = -∞)
            double a = 5.0;
            double b = 4.0;
            double c = a / b;
            Console.WriteLine(c);//值为1.25

            //  ∞ /(-∞) = NaN
            double x1 = double.PositiveInfinity;//正无穷大
            double y1 = double.NegativeInfinity;//负无穷大
            double z1 = x1 / y1;
            Console.WriteLine(z1);//NaN

            double aa = (double)5 / 4;//类型提升; double/int=double
            Console.WriteLine(aa);//值为1.25 
        }
    } 

% 取余操作符

    class Program
    {
        static void Main(string[] args)
        {
            //整数的取余
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(i % 10);
            }

            //浮点数的取余
            double x = 3.5;
            double y = 3;
            Console.WriteLine(x % y);//值为0.5
        }
    }

4.加减操作符

+ 加法操作符

    class Program
    {
        static void Main(string[] args)
        {
            var x = 3.0 + 4;//类型提升
            Console.WriteLine(x.GetType().Name);//Double
            Console.WriteLine(x);

            //连接字符串
            string s1 = "123";
            string s2 = "abc";
            string s3 = s1 + s2;
            Console.WriteLine(s3);//123abc
        }
    } 

- 减法操作符

    class Program
    {
        static void Main(string[] args)
        {
            var x = 3 - 2.0;//类型提升
            Console.WriteLine(x.GetType().Name);//Double
            Console.WriteLine(x);
        }
    } 

5.位移操作符

  数据在内存中的二进制的结构,向左或向右进行一定位数的平移。
  在没有溢出的情况下,左移就是乘 2 ,右移就是除 2

    class Program
    {
        static void Main(string[] args)
        {
            //左移;最高位补位:都是0
            int x = 7;
            int y = x << 2;//在没有溢出的情况下,左移:7*2^2
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            Console.WriteLine("x的二进制:"+strX);
            Console.WriteLine("y的二进制"+strY+"\r\n");
            Console.WriteLine(y);//值为28

            //右移;最高位补位:正数补0,负数补1
            int a = 7;
            int b = a >> 2;//在没有溢出的情况下,右移:/2^2            
        }
    } 

在这里插入图片描述

6.关系和类型检测操作符

< > <= >= 关系操作符

    class Program
    {
        static void Main(string[] args)
        {
            //比较数值大小
            int x = 5;
            double y = 4.0;
            var result = x > y;
            Console.WriteLine(result.GetType().Name);//Boolean
            Console.WriteLine(result);//True


            //比较字符类型—Unicode码
            char char1 = 'a';
            char char2 = 'A';            
            var result1 = char1 > char2;
            Console.WriteLine(result1);//True

            ushort u1 = (ushort)char1;
            ushort u2 = (ushort)char2;
            Console.WriteLine(u1);//'a'-97
            Console.WriteLine(u2);//'A'-65


            //比较字符串
            string str1 = "abc";
            string str2 = "Abc";
            Console.WriteLine(str1.ToLower() == str2.ToLower());//False 忽略大小写
           
            int strRes = string.Compare(str1, str2);//0是相等;负值是<;正值是>;
            Console.WriteLine(strRes);
        }
    }   

is as 类型检测操作符

在这里插入图片描述

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            //is操作符:检验一个对象是不是某个类型的对象 ∈
            Teacher t = new Teacher();
            var result = t is Teacher;//t是实例new Teacher
            Console.WriteLine(result.GetType().Name);//Boolean
            Console.WriteLine(result);//True

            Teacher t1 = new Teacher();
            var result1 = t1 is Human;//t是实例new Teacher;Teacher类继承自Human类
            Console.WriteLine(result1.GetType().Name);
            Console.WriteLine(result1);//True

            Car car = new Car();
            Console.WriteLine(car is object);//True

            Human h = new Human();
            var result2 = h is Teacher;
            Console.WriteLine(result2);//False


            //as操作符
            object o = new Teacher();
            if (o is Teacher)//True
            {
                Teacher t2 = (Teacher)o;
                t2.Teach();
            }

            object o1 = new Teacher();
            Teacher tea = o1 as Teacher;
            if (tea != null)
            {
                t.Teach();
            }
        }
    }

    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("Eating…");
        }
    }

    class Human : Animal//Human类继承自Animal类
    {
        public void Think()
        {
            Console.WriteLine("Who I am?");
        }
    }

    class Teacher : Human//Teacher了继承自Human类
    {
        public void Teach()
        {
            Console.WriteLine("I teach programming.");
        }
    }

    class Car
    {
        public void Run()
        {
            Console.WriteLine("Running…");
        }
    }
}

7.逻辑与 &| 异或 ^

  一般在操作二进制数据,图像数据时用。

  按位与:1-true,0-false;真真=真,真假=假,假假=假
  按位或:1-true,0-false;真真=真,真假=真,假假=假
  按位异或:1-true,0-false;真真=假,真假=真,假假=假

    class Program
    {
        static void Main(string[] args)
        {
            //按位与:1-true,0-false;真真=真,真假=假,假假=假
            int x = 7;
            int y = 28;
            int z = x | y;
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
            Console.WriteLine(strX);
            Console.WriteLine(strY);
            Console.WriteLine(strZ);


            //按位或:真真=真,真假=真,假假=假

            //按位异或:真真=假,真假=真,假假=假
        }
    }

7.条件与 && 条件或 ||

    class Program
    {
        static void Main(string[] args)
        {
            //条件与
            int x = 5;
            int y = 4;
            int a = 100;
            int b = 200;
            if (x>y && a<b)
            {
                Console.WriteLine("Hello");
            }

            //条件或
            int x1 = 3;
            int y1 = 4;
            int a1 = 100;
            int b1 = 200;
            if (x1 > y1 || a1 < b1)
            {
                Console.WriteLine("Hello");
            }
        }
    }

☆条件与,条件或的短路效应

  尽量避开这种短路效应

  && 左边为False,右边会不执行
  || 左边已经成立,右边会不执行

    class Program
    {
        static void Main(string[] args)
        {         
            //条件与,条件或的短路效应
            int x2 = 3;
            int y2 = 4;
            int a2 = 3;
            if (x2>y2 && a2++>3)//&& 左边为False,右边不执行
            {
                Console.WriteLine("Hello");
            }
            Console.WriteLine(a2);//3

            int x3 = 5;
            int y3 = 4;
            int a3 = 3;
            if (x3 > y3 && a3++ > 3)
            {
                Console.WriteLine("Hello");
            }
            Console.WriteLine(a3);//4

            int x4 = 5;
            int y4 = 4;
            int a4 = 3;
            if (x4 > y4 || a4++ > 3)//|| 左边已经成立,右边不执行
            {
                Console.WriteLine("Hello");
            }
            Console.WriteLine(a4);//3

            int x5 = 3;
            int y5 = 4;
            int a5 = 3;
            if (x5 > y5 || ++a5 > 3)//|| 左边不成立,执行右边
            {
                Console.WriteLine("Hello");
            }
            Console.WriteLine(a5);//4
        }
    }

8.?? null 合并操作符

    class Program
    {
        static void Main(string[] args)
        {
            //可空类型          
            int? x = null; //Nullable<int> x = null;
            x = 100;
            Console.WriteLine(x);//100            


            int? x1 = null;
            int y1 = x1 ?? 1;//如果x是null,赋值1
            Console.WriteLine(y1);
        }
    }

9.?: 条件操作符

    class Program
    {
        static void Main(string[] args)
        {
            int x = 80;
            string str = string.Empty;
            if (x >= 60)
            {
                str = "Pass";
            }
            else
            {
                str = "Failed";
            }
            Console.WriteLine(str);


            //使用条件操作符
            int x1 = 80;
            string str1 = (x1 >= 60) ? "Pass" : "Failed";         
            Console.WriteLine(str1);                      
        }
    }

10.赋值和lambda表达式

    class Program
    {
        static void Main(string[] args)
        {
            int x = 5;
            x += 1;//x = x + 1;
            Console.WriteLine(x);


            int a = 7;
            a <<= 2;//a=a<<2
            Console.WriteLine(a);//7*2*2=28


            int b = 5;
            int c = 6;
            int d = 7;
            int e = b += c *= d;//从右往左:c=c*d=42;b=b+c=47;e=47
        }                             
    }
发布了47 篇原创文章 · 获赞 74 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/IT_xiao_guang_guang/article/details/104555620
今日推荐