熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C++編程人員容易犯的10個C#錯誤(下)

2013-11-13 10:52:59  來源: .NET編程 

  錯誤虛方法必須被明確地覆蓋

  在C#語言中編程人員在覆蓋一個虛方法時必須顯性地使用override關健字假設一個Window類是由A公司編寫的ListBox和RadioButton類是由B公司的和編程人員在購買的A公司編寫的Window類的基礎上編寫的B公司的編程人員對包括Window類未來的變化情況在內的設計知之甚少

  如果B公司的一位編程人員要在ListBox上添加一個Sort方法

  public class ListBox : Window
  {
   public virtual void Sort() {}
  }

  在A公司發布新版的Window類之前這不會有任何問題如果A公司的編程人員也在Window類中添加了一個Sort方法

  public class Window
  { 
   //
   public virtual void Sort() {}
  }

  在C++中Windows類中的Sort方法將成為ListBox類中Sort方法的基礎方法在希望調用Windows類中的Sort方法時ListBox類中的Sort方法就會被調用在C#中虛擬函數總是被認為是虛擬調度的根也就是說一旦C#發現一個虛擬的方法就不會再在虛擬鏈中查找其他虛擬方法如果ListBox再次被編譯編譯器就會生成一個警告信息

  \classcs(): warning CS: ListBoxSort() hides
  inherited member WindowSort()

  要使當前的成員覆蓋原來的方法就需要添加override關健字或者添加new關健字

  要消除警告信息編程人員必須搞清楚他想干什麼可以在ListBox類中的Sort方法前添加new表明它不應該覆蓋Window中的虛方法

  public class ListBox : Window
  {
   public new virtual void Sort() {}

  這樣就可以清除警告信息如果編程人員確實希望覆蓋掉Window中的方法就必須使用override關健字來顯性地表明其意圖

  錯誤類成員變量的初始化

  C#中的初始化與C++中不同假設有一個帶有private性質的成員變量age的Person類Employee是由繼承Person類而生成的它有一個private性質的salaryLevel成員變量在C++中我們可以在Employee的構造器的初始化部分初始化salaryLevel如下面的代碼所示

  Employee::Employee(int theAge int theSalaryLevel):
  Person(theAge) // 初始化基礎類
  salaryLevel(theSalaryLevel) // 初始化成員變量
  {
   // 構造器的代碼
  }

  這種方法在C#中是非法的盡管仍然可以初始化基礎類但象上面的代碼那樣對成員變量初始化就會引起編譯錯誤在C#中我們可以在定義成員變量時的同時對它進行初始化

  Class Employee : public Person
  {
   // 成員變量的定義
   private salaryLevel = ; // 初始化
  }
  
  注意必須明確地定義每個變量的訪問權限

  錯誤布爾型變量與整型變量是兩回事兒

  if( someFuncWhichReturnsAValue() )

  在C#中布爾型變量與整型變量並不相同因此下面的代碼是不正確的

  if( someFuncWhichReturnsAValue() )

  if someFuncWhichReturnsAValue返回零表示false否則表示true的想法已經行不通了這樣的好處是原來存在的將賦值運算與相等相混淆的錯誤就不會再犯了因此下面的代碼

  if ( x = )

  在編譯時就會出錯因為x=只是把賦給了X而不是一個布爾值

  錯誤switch語句中會有些語句執行不到

  在C#中如果一個switch語句執行了一些操作則程序就可能不能執行到下一個語句因此盡管下面的代碼在C++中是合法的但在C#中卻不合法

  switch (i)
  {
   case :
   CallFuncOne();
   case : // 錯誤不會執行到這裡
   CallSomeFunc();
  }

  要實現上面代碼的目的需要使用一個goto語句

  switch (i)
  {
   case :
   CallFuncOne();
   goto case ;
   case :
   CallSomeFunc();
  }

  如果case語句不執行任何代碼則所有的語句都會被執行如下面的代碼

  switch (i)
  {
   case : // 能執行到
   case : // 能執行到
   case :
   CallSomeFunc();
  }

  錯誤C#中的變量要求明確地賦值

  在C#中所有的變量在使用前都必須被賦值因此可以在定義變量時不對它進行初始化如果在把它傳遞給一個方法前必須被賦值

  如果只是通過索引向方法傳遞一個變量並且該變量是方法的輸出變量這是就會帶來問題例如假設有一個方法它返回當前時間的小時如果象下面這樣編寫代碼

  int theHour;
  int theMinute;
  int theSecond;
  timeObjectGetTime( ref theHour ref theMinute ref theSecond)

  如果在使用theHourtheMinute和theSecond這三個變量之前沒有對它們進行初始化就會產生一個編譯錯誤

  Use of unassigned local variable theHour
  Use of unassigned local variable theMinute
  Use of unassigned local variable theSecond

  我們可以通過將這些變量初始化為或其他對方法的返回值沒有影響的值以解決編譯器的這個小問題

  int theHour = ;
  int theMinute = ;
  int theSecond = ;
  timeObjectGetTime( ref theHour ref theMinute ref theSecond)

  這樣就有些太麻煩了這些變量傳遞給GetTime方法然後被改變而已為了解決這一問題C#專門針對這一情況提供了out參數修飾符它可以使一個參數無需初始化就可以被引用例如GetTime中的參數對它本身沒有一點意義它們只是為了表達該方法的輸出在方法中返回之前Out參數中必須被指定一個值下面是經過修改後的GetTime方法

  public void GetTime(out int h out int m out int s)
  {
   h = Hour;
   m = Minute;
   s = Second;
  }

  下面是新的GetTime方法的調用方法

  timeObjectGetTime( out theHour out theMinute out theSecond);


From:http://tw.wingwit.com/Article/program/net/201311/14698.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.