C#基本語法&問題集錦

1. *傳入某個屬性的**set**方法的隱含參數的名稱是什麼?*
   value,它的類型和屬性所聲名的類型相同。
   2. *如何在**C#**中實現繼承?**
   *在類名後加上一個冒號,再加上基類的名稱。
   3. *C#**支持多重繼承麼?**
   *不支持。可以用接口來實現。
   4. *被**protected**修飾的屬性**/**方法在何處可以訪問?**
   *在繼承或間接繼承與這個類的子類中可以訪問。
   5. *私有成員會被繼承麼?**
   *會,但是不能被訪問。所以看上去他們似乎是不能被繼承的,但實際上確實被繼承了。
   6. *請描述一下修飾符**protected internal**。**
   *被protected internal修飾的屬性/方法只能在它的在同一個程序集(Assembly)中的子類被訪問。
   7. *C#**
   提供一個默認的無參數構造函數,當我實現了另外一個有一個參數的構造函數時候,還想保留這個無參數的構造函數。這樣我應該寫幾個構造函數?**
   *兩個,一旦你實現了一個構造函數,C#就不會再提供默認的構造函數了,所以需要手動實現那個無參數構造函數。
   8. *C#**中所有對象共同的基類是什麼?**
   *System.Object.
   9. *重載和覆寫有什麼區別?**
   *重載提供了對一個方法簽名的不同參數調用的實現。覆寫提供了子類中改變父類方法行爲的實現。
   10. *在方法定義中,**virtual**有什麼含意?**
   *被virtual修飾的方法可以被子類覆寫。
   11. *能夠將非靜態的方法覆寫成靜態方法麼?**
   *不能,覆寫方法的簽名必須與被覆寫方法的簽名保持一致,除了將virtual改爲override。
   12. *可以覆寫私有的虛方法麼?**
   *不可以,甚至子類中無法訪問父類中的私有方法。
   13. *能夠阻止某一個類被其他類繼承麼?*
   可以,使用關鍵字sealed。
   14. *能夠實現允許某個類被繼承,但不允許其中的某個方法被覆寫麼?**
   *可以,標記這個類爲public,並標記這個方法爲sealed。
   15. *什麼是抽象類(**abstract class**)?**
   *一種不可以被實例化的類。抽象類中一般含有抽象方法,當然也可有具體實現。繼承類只有實現過所有抽象類的抽象方法後才能被實例化。
   16. *何時必須聲明一個類爲抽象類?**
   *當這個類中包含抽象方法時,或是該類並沒有完全實現父類的抽象方法時。
   17. *接口(**interface**)是什麼?**
   *只含有共有抽象方法(public abstract method)的類。這些方法必須在子類中被實現。
   18. *爲什麼不能指定接口中方法的修飾符?**
   *接口中的方法用來定義對象之間通信的契約,指定接口中的方法爲私有或保護沒有意義。他們默認爲公有方法。
   19. *可以繼承多個接口麼?**
   *當然。
   20. *那麼如果這些接口中有重複的方法名稱呢?**
   *這種情況中你可以決定如何實現。當然需要特別得小心。但是在編譯環節是沒有問題的。
   21. *接口和抽象類的區別是什麼?**
   *接口中所有方法必須是抽象的,並且不能指定方法的訪問修飾符。抽象類中可以有方法的實現,也可以指定方法的訪問修飾符。
   22. *如何區別重載方法?**
   *不同的參數類型,不同的參數個數,不同的參數順序。
   23. *const**和**readonly**有什麼區別?*
   const關鍵字用來聲明編譯時常量,readonly用來聲明運行時常量。
   24. *System.String **和**System.StringBuilder**有什麼區別?**
   *System.String是不可變的字符串。System.StringBuilder
   存放了一個可變的字符串,並提供一些對這個字符串修改的方法。

*抽象方法* <http://vi.xmlol.com/blogview.asp?logID=757>
public abstract bool WithDraw(...)*;*
*特點*:
1 抽象方法是必須被派生類覆寫的方法
2 抽象方法可以看作是沒有實現體的虛方法。
3 如果類中包含抽象方法,那麼該類必須被聲明爲抽象類,而不管該類中是否包括其他一般方法。
*overload & override*
*重載*:
public bool BankList(double amt,string name)
public string BankList(double amt)
*特點*:
1 方法名必須相同
2 參數列表必須不同
3 返回值類型可以不同

*覆寫*
子類中爲實現自己的需要來重複定義某個方法的不同實現。比如我們覆寫ToString()來輸出我們想要的格式。
只有虛方法和抽象方法才能覆寫
*特點*:
1 方法名必須相同
2 參數類型必須相同
3 返回值必須相同

設計模式是在實際開發過程中通過不斷重構得到的,不是一上來就開始用設計模式的。
面向對象強調各個類的責任,新增類儘量不去影響原有類
面向對象更能適應需求的變化,即可擴展性強

*對象*的定義:

   1. 從概念上講,對象是某種擁有責任的抽象
   2. 從規格層面上講,對象是一系列可以被其他對象使用的公共接口
   3. 從語言實現層面講,對象封裝了代碼和數據

How to:
遵循一定的面向對象設計原則
熟悉一些典型面向對象設計模式

針對設計原則到設計模式:

   1. 針對接口編程,而不是針對實現編程.客戶(也指程序)無需知道所使用對象的類型,只需知道對象擁有客戶需要的接口。

2.      優先使用對象組合,而不是類繼承。類繼承是"白箱操作",對象組合是"黑箱操作"
。繼承破壞了類的封裝性,子類與父類的耦合度高。對象組合只要求對象具有良好的接口,子類父類的耦合度低。
具體原則:

   1. 單一職責原則:一個類僅有一個引起他變化的原因
   2. 開放性封閉原則:類對擴展開放,對修改封閉
   3. 子類必須能夠替換他們的基類
   4. 高層模塊不應該依賴於低層模塊,但二者均依賴於抽象;抽象不應依賴於實現細節,實現細節應依賴於抽象
   5. 接口隔離原則:不應強迫客戶程序依賴於他們不用的方法

*接口(Interface)的作用<http://blog.csdn.net/ChengKing/archive/2005/11/16/530684.aspx>
*
繼承"基類"跟繼承"接口"都能實現某些相同的功能,但有些接口能夠完成的功能是隻用基類無法實現的
1.接口用於描述一組類的公共方法/公共屬性. 它不實現任何的方法或屬性,只是告訴繼承它的類至少要實現哪些功能,繼承它的類可以增加自己的方法.
2.使用接口可以使繼承它的類: 命名統一/規範,易於維護.比如:  兩個類 "狗"和"貓",如果它們都繼承了接口"動物",其中動物裏面有個方法
Behavior(),那麼狗和貓必須得實現Behavior()方法,並且都命名爲Behavior這樣就不會出現命名太雜亂的現象.如果命名不是
Behavior(),接口會約束即不按接口約束命名編譯不會通過.

3.提供永遠的接口。當類增加時,現有接口方法能夠滿足繼承類中的大多數方法,沒必要
  重新給新類設計一組方法,也節省了代碼,提高了開發效率.
*C#_**值類型*
1. 值類型主要包括兩類:struct(結構)類型和枚舉類型。
2. struct(結構)類型包括用戶自定義的struct(結構)類型和內置的簡單類型。
3. 內置的簡單類型包括Numeric數值類型和bool類型。
4. Numeric數值類型包括三類:整型、浮點型和Decimal。
5. char類型屬於整型範疇,表示Unicode字符。
6. Decimal表示數值範圍最大,適合於財務、貨幣計算。
7. 浮點型包括:float型和double型。
8. 值類型的變量本身包含數值,對變量賦值也只是生成了一個副本。
9. 值類型與引用類型不用的是,從值類型不可能派生出新的類型,值類型之間沒有繼承關係。不能繼承,也不能被別的類型繼承。
10. null是引用類型變量的默認值,只能用於引用類型,所以對值類型賦null是錯誤的。
11. 每種值類型都有一個默認構造函數(不帶參數的構造函數)初始化該類型的默認值。
12. c#中的變量經過初始化後纔可能使用,如果沒有初始化,又沒有使用,會出現個警告,但不會出錯,但如果使用了就會出錯。
13. 舉例:int i;初始化有兩種辦法:因爲int是一種結構,系統提供了一個默認的構造函數i = new Int();也可以i = 0;
14. 每種值類型都有一個默認的初值,可以查看msdn幫助,默認值表。引用類型默認初值是null。

*C#**中結構與類的區別*
 一.*類與結構的示例比較:*
結構示例:
public struct Person
{ string Name;
   int height;
   int weight
public bool overWeight()
{    //implement something

}
}

 類示例:
   public class TestTime
   {  int hours;
 int minutes;
 int seconds;
 public void passtime()
{
 //implementation of behavior
}

   }
 調用過程:
 public class Test
 {
public static ovid Main
{
   Person Myperson=new Person      //聲明結構
   TestTime Mytime=New TestTime    //聲明類
}
}

從上面的例子中我們可以看到,類的聲明和結構的聲明非常類似,只是限定符後面是 struct 還是 class
的區別,而且使用時,定義新的結構和定義新的類的方法也非常類似。那麼類和結構的具體區別是什麼呢?

二 .類與結構的差別
*1.**  **值類型與引用類型*
結構是值類型:值類型在堆棧上分配地址,所有的基類型都是結構類型,例如:int 對應System.int32 結構,string 對應
system.string 結構 ,通過使用結構可以創建更多的*值類型*
類是引用類型:引用類型在堆上分配地址
堆棧的執行效率要比堆的執行效率高,可是堆棧的資源有限,不適合處理大的邏輯複雜的對象。所以結構處理作爲基類型對待的小對象,而類處理某個商業邏輯
因爲結構是值類型所以結構之間的賦值可以創建新的結構,而類是引用類型,類之間的賦值只是複製引用
*注:*
1.雖然結構與類的類型不一樣,可是他們的基類型都是對象(object),c#中所有類型的基類型都是object
2.雖然結構的初始化也使用了New 操作符可是結構對象依然分配在堆棧上而不是堆上,如果不使用"新建"(new)
,那麼在初始化所有字段之前,字段將保持未賦值狀態,且對象不可用
 * 2.繼承性*
*   *  結構:不能從另外一個結構或者類繼承,本身也不能被繼承,雖然結構沒有明確的用sealed聲明,可是結構是隱式的sealed .
     類:完全可擴展的,除非顯示的聲明sealed 否則類可以繼承其他類和接口,自身也能被繼承
    * 注*:雖然結構不能被繼承可是結構能夠繼承接口,方法和類繼承接口一樣
*例如*:結構實現接口
* *interface IImage
{
    void Paint();

 

}

struct Picture : IImage
{
    public void Paint()
    {
         // painting code goes here
    }
    private int x, y, z; // other struct members

 

}

 *3**.內部結構:*
結構:
沒有默認的構造函數,但是可以添加構造函數
    沒有析構函數
    沒有 abstract 和 sealed(因爲不能繼承)
    不能有protected 修飾符
    可以不使用new 初始化
在結構中初始化實例字段是錯誤的
類:
 有默認的構造函數
 有析構函數
 可以使用 abstract 和 sealed
有protected 修飾符
必須使用new 初始化

三*.如何選擇結構還是類*
*   *討論了結構與類的相同之處和差別之後,下面討論如何選擇使用結構還是類:
1.  堆棧的空間有限,對於大量的邏輯的對象,創建類要比創建結構好一些
2.   結構表示如點、矩形和顏色這樣的輕量對象,例如,如果聲明一個含有 1000
個點對象的數組,則將爲引用每個對象分配附加的內存。在此情況下,結構的成本較低。
3.  在表現抽象和多級別的對象層次時,類是最好的選擇
4.  大多數情況下該類型只是一些數據時,結構時最佳的選擇
 *c#修飾符*
符用於限定類型以及類型成員的申明,c#中有13種修飾符,按功能可分爲三部分:存取修飾符,類修飾符和成員修飾符.
存取修飾符:
public:存取不受限制.
private:只有包含該成員的類可以存取.
internal:只有當前工程可以存取.
protected:只有包含該成員的類以及繼承的類可以存取.
類修飾符:
abstract:可以被指示一個類只能作爲其它類的基類.
sealed:指示一個類不能被繼承.
成員修飾符:
abstract:指示該方法或屬性沒有實現.
const:指定域或局部變量的值不能被改動.
event:聲明一個事件.
extern:指示方法在外部實現.
override:對由基類繼承成員的新實現.
readonly:指示一個域只能在聲明時以及相同類的內部被賦值.
static:指示一個成員屬於類型本身,而不是屬於特定的對象.
virtual:指示一個方法或存取器的實現可以在繼承類中被覆蓋

 
發佈了7 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章