源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C#语法相比其它语言比较独特的地方(三)

  • 时间:2022-01-15 08:32 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C#语法相比其它语言比较独特的地方(三)
[b]1.在C++中允许从一个case贯穿到另一个case标签 [/b]比如:
[u]复制代码[/u] 代码如下:
int a =1; switch(a) {   case 1:      some statements;   case 2;      other statements;      break; }
第一个case和第二个case之间可以没有break 而在C#中这个break不能省略. [b]3.as和is[/b]只会检测待转化类型的类型,而不会进行其它操作,所以只有当转化类型是目标类型或者目标类型的子类(当然如果目标类型是接口,并且待转化类型实现了该接口也可以)才能转换成功. 强制转化,会调用系统定义(比如float转化为int类型)或自己定义的转化函数(通过implicit operator定义). 从常规的需求来看,大部分情况下,推荐使用as转换. 但要注意as不能用于value type.因为在转换不成功的时候返回null,而value type不能为 null.这时可以考虑用is.
[u]复制代码[/u] 代码如下:
object o = 1; int i = 0; if(o is int) i = (int)o;
[b]6.const是编译时常量 [/b]readonly是运行时常量 推荐使用static readonly代替const const变量被硬编码进assembly,有版本问题. C#只是用sealed替代了fianl,另外C#的派生类在默认情况下不会override基类方法,只有当基类方法用关键字virtual标志,并且子类显式用override标志方法时才会override.这样也有效地解决了版本问题. [b]7.delegate在本质上就是函数指针.[/b] 因为委托还引发了sun和MS的论战. Anders早在Borland的时候就在Delphi中引入了delegate,后来跑到MS,弄J#的时候又添加进了delegate,Sun很不满意,说他们破坏了Java语言的特性. 到了C#,Anders终于可以名正言顺地添加delegate了. ------------------------------- 狗尾续貂(二) [b]1.internal protected[/b]取的是internal和protected的并集,即在同一个Assembly或者不同 的Assembly内但是继承自该类都可以访问. [b]3..NET FrameWork采用了字符串缓冲池技术. [/b]比如 string a = "test";和string b = "test";a和b指向内存中的同一块区域. 另外C#中有几种判等方式,是否重写可参照如下规则:
[u]复制代码[/u] 代码如下:
public static bool ReferenceEquals( object left, object right ); public static bool Equals ( object left, object right ); public virtual bool Equals( object right); public static bool operator==( MyClass left, MyClass right );
上述四个方法override应该遵循如下规则: 1.前两个无论如何不要override 2.第三个和第四个在自定义类型是ValueType的时候要改写 3.当自定义类型是ReferenceType的时候,如果想改变RefrenceType默认的用对象标志判等的方式,可以改写第三个 4.当自定义类型是RefrenceType的时候,最好不要改写operator==. 下面分别给出上述规则的原因: 1. A.ReferenceEquals()这个方法当且仅当两个变量指向同一对象的时候才相等,它的实现是比较对象标志(Object Identity,任何对象在创建的时候都会生成一个OI),所以任何值类型用ReferenceEquals()比较所得到的结果都是false,即使跟自己比较也是,因为要装箱,装箱的结果肯定不是同一个对象.所以这个方法也就没有改写的必要.object的ReferenceEquals()是实现这种比较最好的方式. B.Equals (object left, object right )这个方法用于在不知道待比较的参数是何种类型的时候.那如何比较两个变量是否相等那?很简单,把比较相等的职责交给其中一个待比较变量的Equals方法,上述方法的实现大概如下所述:
[u]复制代码[/u] 代码如下:
public static bool Equals( object left, object right ) {   // Check object identity   if (left == right )     return true;   // both null references handled above   if ((left == null) || (right == null))     return false;   return left.Equals (right); }
之所以不要重写上述两个方法,是因为两者都很好的实现了各自的语意. 2.为什么是值的时候要重写第三个方法? ValueType是所有值类型的基类,由于要实现值相等的语意,它重写了object的Equals方法,但是在不知道派生类变量和其类型的情况下,ValueType的Equals在实现的时候只能用反射来比较,这样的效率是很低的,所以任何自定义的值类型都要重写Equals,以避免用ValueType的默认实现带来的反射的效率损失. 3.object的实例Equals方法的默认实现跟ReferenceEqual一样,是通过比较对象标志来实现的,有些ReferenceType需要值相等的语意,比如string,这是就要改写实例Equals. 4..Net FrameWork期望所有的ReferenceType的operator==保留引用语意. 相等在语意上必须满足三点 1.自反       a=a必须永远成立; 2.对称       a=b则b=a; 3.传递       a=b;b=c则a=c
[u]复制代码[/u] 代码如下:
public class Foo {   public override bool Equals( object right )   {     //1.判断待比较变量引用是否为空     if (right == null)       return false;  //2.是否指向同一实例,如果是同一实例则必然相等.     if (object.ReferenceEquals( this, right ))       return true;     //3. 判断类型是否相同     if (this.GetType() != right.GetType())       return false;     // 4.比较内容     return CompareFooMembers(       this, right as Foo );   } }
第三步如果可以转化成this引用的对象不行吗? 答案是不行,必须是类型相同的.举例如下:
[u]复制代码[/u] 代码如下:
public class B {   public override bool Equals( object right )   {     // check null:     if (right == null)       return false;     // Check reference equality:     if (object.ReferenceEquals( this, right ))       return true;     // Problems here, discussed below.     B rightAsB = right as B;     if (rightAsB == null)       return false;     return CompareBMembers( this, rightAsB );   } } public class D : B {   // etc.   public override bool Equals( object right )   {     // check null:     if (right == null)       return false;     if (object.ReferenceEquals( this, right ))       return true;     // Problems here.     D rightAsD = right as D;     if (rightAsD == null)       return false;     if (base.Equals( rightAsD ) == false)       return false;     return CompareDMembers( this, rightAsD );   } } //Test: B baseObject = new B(); D derivedObject = new D(); // Comparison 1. if (baseObject.Equals(derivedObject))   Console.WriteLine( "Equals" ); else   Console.WriteLine( "Not Equal" ); // Comparison 2. if (derivedObject.Equals(baseObject))   Console.WriteLine( "Equals" ); else   Console.WriteLine( "Not Equal" );
留意一下加粗的部分就知道,如果B的CompareBMembers和D的CompareDMembers比较的元素相等的话,Comparison 1将输出Equals,而Comparison 2将永远输出Not Equal.所以在这种情况下将违反相等语意中的对称性. 所以还是老老实实在第三步Check类型哈. 上面例子中D比B多了一句:
[u]复制代码[/u] 代码如下:
if (base.Equals( rightAsD ) == false)       return false;
很明显,基类的元素肯定要让基类去判断是否相等.但是如果某个类的直接基类是object千万必要调用base.Equals了,要不然跟没有重写实例Equals是一样的效果 4.跟C++的引用不一样,ref和out其实就是指针,在函数之间传递用的是拷贝传值.
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部