C#文法中比較特別之處—狗尾續貂

來源:互聯網
上載者:User
1.在C++中允許從一個case貫穿到另一個case標籤
比如:
int a =1;
switch(a)
{
  case 1:
     some statements;
  case 2;
     other statements;
     break;
}
第一個case和第二個case之間可以沒有break
而在C#中這個break不能省略.
3.
as和is只會檢測待轉化類型的類型,而不會進行其它操作,所以只有當轉化類型是目標類型
或者目標類型的子類(當然如果目標類型是介面,並且待轉化類型實現了該介面也可以)才能
轉換成功.
強制轉化,會調用系統定義(比如float轉化為int類型)或自己定義的轉化函數(通過implic
it operator定義).
從常規的需求來看,大部分情況下,推薦使用as轉換.
但要注意as不能用於value type.因為在轉換不成功的時候返回null,而value type不能為
null.這時可以考慮用is.
object o = 1;
int i = 0;
if(o is int)
i = (int)o;
6.
const是編譯時間常量
readonly是運行時常量
推薦使用static readonly代替const
const變數被寫入程式碼進assembly,有版本問題.
C#只是用sealed替代了fianl,另外C#的衍生類別在預設情況下不會override基類方法,只有當
基類方法用關鍵字virtual標誌,並且子類顯式用override標誌方法時才會override.這樣也
有效地解決了版本問題.
7.
delegate在本質上就是函數指標.
因為委託還引發了sun和MS的論戰.
Anders早在Borland的時候就在Delphi中引入了delegate,後來跑到MS,弄J#的時候又添加進
了delegate,Sun很不滿意,說他們破壞了Java語言的特性.
到了C#,Anders終於可以名正言順地添加delegate了.

-------------------------------

狗尾續貂(二)

1.internal protected取的是internal和protected的並集,即在同一個Assembly或者不同
的Assembly內但是繼承自該類都可以訪問.

3..NET FrameWork採用了字串緩衝池技術.
比如 string a = "test";和string b = "test";a和b指向記憶體中的同一塊地區.
另外C#中有幾種判等方式,是否重寫可參照如下規則:

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方法,上述方法的實現大概如下所述:

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,以避免用Va
lueType的預設實現帶來的反射的效率損失.

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

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引用的對象不行嗎?

答案是不行,必須是類型相同的.舉例如下:

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多了一句:
if (base.Equals( rightAsD ) == false)
      return false;
很明顯,基類的元素肯定要讓基類去判斷是否相等.但是如果某個類的直接基類是object
千萬必要調用base.Equals了,要不然跟沒有重寫執行個體Equals是一樣的效果,

4.跟C++的引用不一樣,ref和out其實就是指標,在函數之間傳遞用的是拷貝傳值.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.