标签:重载运算符 limit limited 可空类型 void eva 跳过 false 补充
本章将定义表达式,并描述C#提供的运算符。
运算符是一个符号,它表示返回单个结果的操作。操作数(operand)指作为运算符输入的数据元素。一个运算符会:
表达式是运算符和操作数的字符串。可以作为操作数的结构有:
例:下面的表达式,有3个运算符和4个操作数
字面量(literal)是源代码中键入的数字或字符串,表示一个指定类型的明确的、固定的值。
例:字面量
class Program { static void Main() { Console.WriteLine("{0}",1024);//整数字面量 Console.WriteLine("{0}",3.1416F);//浮点型字面量 Console.WriteLine("{0}",true);//布尔型字面量 } }
对于引用类型变量,字面量null表示变量没有设置为内存中的数据。
例:不同的整数类型
236 //整型 236L //长整型 236U //无符号整型 236UL//无符号长整型
整数字面量还可以写成十六进制(hex)形式
实数字面量组成如下:
例:实数字面量的不同格式
float f1=236F; double d1=236.712; double d2=.351; double d3=6.338e-26;
无后缀的实数字面量默认是double类型。
字符字面量可以是下面任意一种:
例:字符字面量的不同格式
char c1=‘d‘; char c2=‘\n‘; char c3=‘\x0061‘; char c4=‘\u005a‘;
一些特殊字符及其编码见下图
两种字符串字面量类型:
常规字符串字面量包含:
string st1="Hi there!"; string st2="Val\t5,val\t10"; string st3="Add\x000ASome\u0007Interest";
逐字字符串以@为前缀,它有以下特征:
string rst1="Hi there!"; string vst1=@"Hi there!"; string rst2="It started,\"Four score and seven...\""; string vst2=@"It started,""Four score and seven..."""; string rst3="Value 1 \t 5,val2 \t 10"; string vst3=@"Value 1 \t 5,val2 \t 10"; string rst4="C:\\Program Files\\Microsoft\\"; string vst4=@"C:\Program Files\Microsoft\"; string rst5=" Print \x000A Multiple \u000A Lines"; string vst5=@" Print Multiple Lines";
编译器让相同的字符串字面量共享堆中同一内存位置以节约内存
表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式最终值发生差别。
正如小学的先乘除再加减,C#中运算符也有优先级。
表达式中运算符优先级不同的,从高到低依次运算。但若是运算符优先级相同怎么办?
当连续运算符有相同优先级时,求值顺序由操作结合性决定。
求余运算符(%)用第二个操作数除第一个操作数,并返回余数。
求余运算符是二元左结合运算符。
它们都是二元左结合运算符,对其操作数进行比较并返回bool值。
与C和C++不同,在C#中数字不具有布尔意义
int x=5; if(x)//错,x是int类型,不是布尔型 if(x==5)//对,返回true
比较操作和相等性操作
对于大多数引用类型来说,比较它们的相等性,将只比较它们的引用。
下图阐明了引用类型的比较
string类型也是引用类型,但它的比较方式不同。比较字符串的相等性,将比较它们的长度和内容(区分大小写)
将在第15章介绍的委托也是引用类型,并且也使用深比较。比较委托的相等性时,让两个委托都是null,或两者的调用列表有相同数目成员,并且调用列表想匹配,则返回true。
比较数值表达式,将比较类型和值。比较enum类型时,比较操作数的实际值。枚举在第13章阐述。
无论运算符前置还是后置,只影响返回给表达式的值。在语句执行后,最终存放在操作数的变量的值相同
条件逻辑运算符使用“短路”(short circuit)模式操作,意思是,如果计算Expr1之后结果已确定,那么它会跳过Expr2的求值。
例:短路示例
bool bVal; bVal=(1==2)&&(2==2); //左侧false,接着&&运算,结果必是false,所以跳过了右侧的运算 bVal=(1==1)||(1==2); //左侧true,接着是||运算,结果必是true,所以跳过了右侧的运算
因为短路特性,不要在Exp2中放置带有副作用的表达式(比如改变一个值),因为可能不会计算。
bool bVal;int iVal=10; bVal=(1==2)&&(9==iVal++);//结果:bVal=False,iVal=10; ↑ ↑ False 不会计算
例:移位运算符示例
int a,b,x=14; a=x<<3; b=x>>3; Console.WriteLine("{0}<<3={1}",x,a); Console.WriteLine("{0}>>3={1}",x,b);
赋值运算符是二元右结合运算符
复合赋值
复合赋值运算符允许一种速记方法,在某些情况下避免左边的变量在右边重复出现。
复合赋值不仅更短,也易于理解。
x=x+(y-z); x+=y-z;
条件运算符是一种强大且简洁的方法,基于条件的结果,返回两个值之一。
条件运算符是三元运算符
if...else if(x<y) intVar=5; else intVar=10; 条件运算符 intVar=x<y?5:10;
if…else语句是控制流语句,它应当用来做两个行为中的一个。条件运算符返回一个表达式,它应当用于返回两个值中的一个。
用户定义的转换将在第16章详讲,在这里稍微提一下。
声明隐式转换的语法如下。
必需的 目标类型 源数据 ↓ ↓ ↓ public static implicit operator TargetType(SourceType Identifier) { ... return ObjectOfTargetType; }
显式转换的语法与之相同,但要用explicit替换implicit
例:将LimitedInt转换为int
class LimitedInt { const int MaxValue=100; const int MinValue=0; public static implicit operator int(LimitedInt li) { return li.TheValue; } public static implicit operator LimitedInt(int x) { var li=new LimitedInt(); li.TheValue=x; return li; } private int _theValue=0; public int TheValue { get{return _theValue;} set { if(value<MinValue) _theValue=0; else _theValue=value>MaxValue?MaxValue:value; } } class Program { static void Main() { LimitedInt li=500; int value=li; Console.WriteLine("li:{0},value:{1}",li.TheValue,value); } } }
显式转换和强制转换运算符
如果把两个运算符声明为explicit,你将不得不在实行转换时显示使用转换运算符。
public static explicit operator int(LimitedInt li) { return li.TheValue; } public static explicit operator LimitedInt(int x) { var li=new LimitedInt(); li.TheValue=x; return li; } static void Main() { LimitedInt li=(LimitedInt)500; int value=(int)li; Console.WriteLine("li:{0},value:{1}",li.TheValue,value); }
输出结果与上例相同
另外有两个运算符,接受一种类型的值,并返回另一种不同的、指定类型的值。这就是is运算符和as运算符。它们将在第16章结尾阐述。
运算符重载允许你定义C#运算符应该如何操作自定义类型的操作数
例:类LimitedInt的两个重载运算符,加运算符和减运算符
class LimitedInt { 必需的 类型 关键字 运算符 操作数 ↓ ↓ ↓ ↓ ↓ public static LimitedInt operator + (LimitedInt x,double y) { var li=new LimitedInt(); li.TheValue=x.TheValue+(int)y; return li; } public static LimitedInt operator - (LimitedInt x) { var li=new LimitedInt(); li.TheValue=0; return li; } ... }
不是所有的运算符都能被重载,可以重载的类型也有限制。
递增和递减运算符可重载。但和预定义的版本不同,重载运算符的前置和后置之间没有区别。
运算符重载不能做下面的事情:
重载运算符应该符合运算符的直观含义。
例:LimitedInt的3个运算符重载
class LimitedInt { const int MaxValue=100; const int MinValue=0; public static LimitedInt operator - (LimitedInt x) { var li=new LimitedInt(); li.TheValue=0; return li; } public static LimitedInt operator - (LimitedInt x,LimitedInt y) { var li=new LimitedInt(); li.TheValue=x.TheValue-y.TheValue>0?(x.TheValue-y.TheValue):0; return li; } public static LimitedInt operator + (LimitedInt x,double y) { var li=new LimitedInt(); li.TheValue=x.TheValue+(int)y; return li; } private int _theValue=0; public int TheValue { get{return _theValue;} set { if(value<MinValue) _theValue=0; else _theValue=value>MaxValue?MaxValue:value; } } class Program { static void Main() { var li1=new LimitedInt(); var li2=new LimitedInt(); var li3=new LimitedInt(); li1.TheValue=10;li2.TheValue=26; Console.WriteLine("li:{0},li2:{1}",li1.TheValue,li2.TheValue); li3=-li1; Console.WriteLine("-{0}={1}",li1.TheValue,li3.TheValue); li3=li2-li1; Console.WriteLine("{0}-{1}={2}",li2.TheValue,li1.TheValue,li3.TheValue); li3=li1-li2; Consoel.WriteLine("{0}-{1}={2}",li1.TheValue,li2.TheValue,li3.TheValue); } } }
typeof运算符返回作为其参数的任何类型的System.Type对象。
例:使用typeof运算符获取SomeClass类的信息
using System.Reflection;//反射 class SomeClass { public int Field1; public int Field2; public void Method1(){} public int Method2(){return 1;} } class Program { static void Main() { var t=typeof(SomeClass); FieldInfo[] fi=t.GetFields(); MethodInfo[] mi=t.GetMethods(); foreach(var f in fi) Console.WriteLine("Field:{0}",f.Name); foreach(var m in mi) Console.WriteLine("Method:{0}",m.Name); } }
GetType方法也会调用typeof运算符,该方法对每个类型的每个对象都有效。
例:使用GetType获取对象类型名称
class SomeClass { } class Program { static void Main() { var s=new SomeClass(); Console.WriteLine("Type s:{0}",s.GetType().Name); } }
本章介绍的运算符是内置类型的标准运算符。本书后面部分会介绍其他特殊用法的运算符及操作数类型。例如,可空类型有一个特殊运算符叫空接合运算符(第25章)。
from: http://www.cnblogs.com/moonache/p/6140985.html
标签:重载运算符 limit limited 可空类型 void eva 跳过 false 补充
原文地址:https://www.cnblogs.com/GarfieldEr007/p/10126560.html