操作符详解
一、操作符概览
- 操作符(Operator)也译为“运算符”
二、操作符的本质
- 操作符的本质是函数(即算法)的“简记法”
- 假如没有发命“+”、只有Add函数,算式3+4+5将可以写成Add(Add(3,4),5);
- 假如没有发明“×”、只有Mul函数,那么算式将只能写成Add(3,Mul(4,5));
static void Main(string[] args)
{
Person person1 = new Person();
Person person2 = new Person();
person1.Name = "Deer";
person2.Name = "Deer’s wife";
List<Person> nation = person1 + person2;// Person.GetMarry(person1, person2);
foreach (var p in nation)
{
Console.WriteLine(p.Name);
}
Console.Read();
}
}
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;
}
}
三、操作符的优先级
- 1、优先级与运算顺序
- 操作符的优先级
- 可以使用圆括号提高被括起来表达式的优先级
- 圆括号可以嵌套
- 不像数学里又方括号和华括号,在C#语言里[]和{}又专门的用途
- 操作符的优先级
四、同级操作符的运算顺序
- 除了带有赋值功能的操作符,同优先级操作符都是由左向右进行运算
- 带有赋值功能的操作符的运算顺序是由右向左
- 与数学运算不同,计算机语言的同优先级运算没有“结合率”
- 3+4+5只能理解为Add(Add(3,4),5),不能理解为Add(Add(3,4),5)
五、基本操作符示例
1、成员访问操作符.
- 访问外层名称空间的子集名称空间
- 访问名称空间的类型
- 访问类型的静态成员
- 访问实例的实例成员
2、方法调用操作符()
class Program
{
static void Main(string[] args)
{
Calculator c = new Calculator();
c.PrintHello();
Action myAction=new Action(c.PrintHello);
myAction();
}
}
class Calculator
{
public double Add(double a,double b)
{ return a + b; }
public void PrintHello()
{ Console.WriteLine("Hello"); }
}
3、元素访问操作符:访问集合当中的元素
//访问数组
int[] myIntArray = new int[] {1,2,3,4,5 };//new int[5];
Console.WriteLine(myIntArray[5]); //System.IndexOutOfRangeException:“索引超出了数组界限
Console.WriteLine(myIntArray[myIntArray.Length -1]);
//访问字典
Dictionary<string, int> stuDic = new Dictionary<string, int>();
for (int i = 0; i <=100; i++)
{
stuDic.Add("Name" + i.ToString(), i);
}
int a = stuDic["Name10"];
Console.WriteLine(a);
4、后置自增后置自减操作符:x++、x--
- 先赋值,再运算
5、new操作符
- 创建类型的实例,并调用实例构造器,初始化器
//匿名类型
var perosn = new { Name = "wang", Age = 34 };
Console.WriteLine(perosn.Name+" "+perosn.Age );
Console.WriteLine(perosn.GetType().Name );
//new 此时是修饰符,用来隐藏父类的方法
class Student
{
public void Report()
{
Console.WriteLine("I'm a student!");
}
}
class CsStudent:Student
{
new public void Report()
{
Console.WriteLine("I'm a CS student!");
}
}
6、typeof&default
//typeof&default //metadate
//typeof
Type t = typeof(int);
Console.WriteLine(t.Namespace );
Console.WriteLine(t.FullName );
Console.WriteLine(t.Name);
for (int i = 0; i < t.GetMethods().Length ; i++)
{
Console.WriteLine(t.GetMethods()[i].Name);
}
//default
int x = default(int);
Console.WriteLine(x); //结构体类型为0;
System.Windows.Forms.Form myForm = new System.Windows.Forms.Form();
Console.WriteLine(myForm==null);
Level level = default(Level);
Console.WriteLine(level); //默认值为枚举类型中的第一个,除非进行了显式赋值
7、checked&unchecked
- 检查溢出
//修饰符
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");
}
//上下文
checked//uncheck
{
try
{
uint y = checked(x + 1);
Console.WriteLine(y);
}
catch (OverflowException ex)
{
Console.WriteLine("there's overflow");
}
}
8、delegate
- 匿名方法
//
this.myButton.Click += myButton_Click;
void myButton_Click(object sender, RoutedEventArgs e)
{
this.myTextBox.Text = "Hello world!";
//throw new NotImplementedException();
}
//
this.myButton .Click+=delegate(object sender,RoutedEventArgs e)
{
this.myTextBox.Text = "Hello world!";
};
//
this.myButton .Click +=(sender,e)=>{this.myTextBox.Text = "Hello world!";};
9、sizeof
- 获取基本数据类型(结构体)的实例(除了string和object)在内存中占用大小
- 在非默认的情况下可以使用sizeof获取自定以的结构体大小是放在不安全内存中
//右键属性,生成勾选允许不安全的代码
unsafe
{
int x=sizeof(Student);
Console.WriteLine(x);
}
struct Student
{
int ID;
long Score;
}
10、->
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;
}
六、一元操作符示例
1、&操作符(取地址操作符)
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;
}
2、-操作符
- 由于类型不对称,可能导致错误
int x = 100;
int y=-x;
Console.WriteLine(y);
int a = int.MinValue;
int b = -a;
Console.WriteLine("a: "+a+" b:"+b);
3、~取反操作符
- 按位取反
int x = 12345678;
int y = ~x;
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(Convert.ToString (x,2).PadLeft(32,'0'));
Console.WriteLine(Convert.ToString (y,2).PadLeft(32,'0'));
4、!操作符
- 只能用来操作bool类型的
bool b1 = false;
bool b2 = !b1;
Console.WriteLine(b1);
Console.WriteLine(b2);
5、前置++和前置--
- 单独使用时和后置++、--一样,但一起用的时候,先运算++(--)再赋值左边
6、强制类型转换(T)
- 类型转换
- 隐式(implicit)类型转换
- 不丢失精度的转换
- 子类向父类转换
- 隐式(implicit)类型转换
Teacher t = new Teacher();
Human h = t;//new Human();
//h没有了Teach的方法
Animal a = h;
//a只有eat的方法了
class Animal
{
public void Eat()
{ Console.WriteLine("Eating……");}
}
class Human:Animal
{
public void Think()
{
Console.WriteLine("Who I am");
}
}
class Teacher:Human
{
public void Teach()
{
Console.WriteLine("Teach");
}
}
- 装箱
- 显式(explicit)类型转换
- 有可能丢失精度,(甚至发生错误)的转换,即cast
- 拆箱
- 使用Convert类
//cast
Console.WriteLine(ushort.MaxValue);
uint x=65536;
ushort y = (ushort)x;
Console.WriteLine(y);
string str1 = Console.ReadLine();
string str2 = Console.ReadLine();
int x=Convert.ToInt32 (str1);
int y=Convert.ToInt32 (str2);
Console.WriteLine(x + y);
- ToString方法与各数据类型的Parse/TryParse方法
//double x = System.Convert.ToDouble(tb1.Text);
//double x = double.Parse(tb1.Text);
double x;
double.TryParse(tb1.Text, out x);
double y = System.Convert.ToDouble(tb2.Text);
double result = x + y;
//this.tb3.Text = System.Convert.ToString (result);
this.tb3.Text = result.ToString();
- 自定义类型转换操作符
Stone stone = new Stone();
stone.Age = 5000;
Monkey wukongSun = stone;
class Stone
{
public int Age;
public static implicit operator Monkey(Stone stone) //explicit(显示)
{
Monkey m=new Monkey ();
m.Age = stone.Age / 500;
return m;
}
}
class Monkey
{
public int Age;
}
- 示例
7、略
七、算数运算符
1、乘法运算符&除法运算符
- 乘法*
- 整数乘法
- int、uint、long、ulong
- 浮点乘法
- float、double
- 小数乘法
- decimal
- 整数乘法
var x = 3 * 4;
Console.WriteLine(x.GetType());
Console.WriteLine(x);
var y = 3.0 * 4.0;
Console.WriteLine(y.GetType ());
Console.WriteLine(y);
- 除法运算符/
- 整数除法
- 除0异常
- 浮点除法
- 可以除0
- 小数除法
- 整数除法
double x = 5.0;
double y = 4.0;
double z = 0;
Console.WriteLine(x/y);
Console.WriteLine(x/z);
double a = double.PositiveInfinity;
Console.WriteLine(a);
double b = double.NegativeInfinity;
Console.WriteLine(b);
Console.WriteLine(a/b);
//1.25
//∞
//∞
//-∞
//NaN
-
取余运算符%
- 整数余数
- 浮点余数
- 浮点余数
-
加法运算符+
- 整数加法
- 浮点加法
- 小数加法
- 枚举加法
- 字符串串联
- 委托组合
-
减法运算符-
- 整数减法
- 浮点减法
- 小数减法
- 枚举减法
- 委托移除
八、位移运算符
1、左移位
2、右移位
int x = 7;
int y = x << 1;
string strX = Convert.ToString(x, 2).PadLeft(32, '0');
string strY = Convert.ToString(y, 2).PadLeft(32, '0');
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(strX);
Console.WriteLine(strY);
九、关系运算符
1、关系和类型检测
2、相等
十、逻辑运算符
1、逻辑“与” &
2、逻辑XOR ^
3、逻辑OR |
4、条件AND &&
5、条件OR ||
6、null合并 ??
int? x = null;
int y = x ?? 1;
//x = 100;
Console.WriteLine(x); ;
Console.WriteLine(y);