文章目录
- 一、操作符概览
- 二、操作符的本质
- 三、优先级与运算顺序
- 四、各类操作符的示例
- 1.基本操作符
- ①
.
成员访问操作符 - ②
f(x)
方法调用操作符 - ③
a[x]
元素访问操作符 - ④
x++
x--
后置自增、自减操作符 - ⑤
typeof
操作符 - ⑥
default
操作符 - ⑦
new
操作符 - ⑧
checked
&unchecked
操作符 - ⑨
delegate
操作符 - ⑩
sizeof
操作符 - ⑪
->
操作符 - 2.一元操作符
- 3.乘法操作符
- 4.加减操作符
- 5.位移操作符
- 6.关系和类型检测操作符
- 7.逻辑与
&
或|
异或^
- 7.条件与
&&
条件或||
- 8.
??
null 合并操作符 - 9.
?:
条件操作符 - 10.赋值和lambda表达式
一、操作符概览
- 操作符(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))
- 3+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
}
}
转载:https://blog.csdn.net/IT_xiao_guang_guang/article/details/104555620