1. 程式人生 > >my questions of C#

my questions of C#

style 接口 只讀 而已 pan 外部 類繼承 接口類 方式

語法

關於類屬性的訪問權限

對於Python來說,並不存在私有屬性——雖然提供了一個雙下劃線的“人為定義”,這使得你在直接訪問時獲取到Exception,但這只是提示你,訪問該屬性是一個危險操作,應該規避這種訪問方式——你還是可以獲取到該內存。

如果只是開發一個exe程序,這個方式簡單而高效——我們僅需要編譯器告訴我們哪些訪問是危險的。因為絕大多數情況下,我們既然設計了某個屬性,就意味著它作為變量,是允許讀寫的——至於錯誤的讀寫,是用戶使用不當的問題!

當然庫(廣義概念的庫,包括統一程序中的輔助類、基類等)的開發就是另一碼事兒了。當某一個對象與外界交互時,外界並不需要知道你的所有細節——接口就夠了,包括接口函數和接口屬性。其他的,是你內部設計的問題,與外界無關。

這裏的外界,還包括兩部分——純粹的外部系統,以及拓展子類。

C# 中,關於屬性,有以下幾種形式:

  • Filed
  • Property
  • Index
  • Attribute

Field,應該作為內部的變量,僅供類內使用(包括protected繼承給子類)。所以一般定義為 protected string _abc;

Property 只讀接口:

  • public string abc => _abc,表示提供 _abc 的訪問接口,但不提供改寫接口。
  • public string abc{get;} ,創建一個屬性,並且只提供訪問(且子類無權限set),相當於 private string _abc; pulic string abc => abc;

Property 讀寫接口: publi string abc{get; set;},這與定義一個Filed: public string abc 作用相同。不同的是,我們可以重寫get/set訪問器,來實現自定義的讀寫操作,如控制寫入參數的範圍。

註意,一般的Property都是public修飾,因為如果不需要外部訪問或僅僅對子類開放,定義為 protected Filed 即可。

總結:C# 訪問是按照外部訪問權限定義關鍵字的,一般的,對於Filed,多定義為protected(除非嚴格禁止子類繼承時,使用private),其作用是存儲數據;而對於Property,一般定義為public,其作用是 存儲數據+外部交互,使用時更像一個接口(函數)。

關於C#多態的思考

https://www.cnblogs.com/brt3/p/9744070.html

架構與模式

抽象類實現接口類的類型沖突(未解決)

在《設計模式:示例與思考》裏介紹橋接模式時,遇到一個問題:最初我的設計是面向接口的:

public interface ISoftWare{
    void run();
}

public interface IHardWare{
    void drive();
    void software_install(ISoftWare software);
    void software_execute();
}

接著,我發現 ISoftWare 和 IHardWare 可以進一步實現:

public abstract class SoftWare: ISoftWare{
    public HardWare env{get;set;}

    protected abstract void function();  // 軟件功能代碼(我們假設功能代碼與環境無關,也就是Java跨平臺特性)
    public void run(){  // run() 就是一個 Template Method.
        this.env.drive();  // 軟件運行需要載入系統運行時
        this.function();
    }
}

但在實現 HardWare 的抽象類時,遇到了問題:

public abstract class HardWare: IHardWare{
    public SoftWare software{get;set;}

    public abstract void drive();
    public void software_install(SoftWare software){  // we need change the ISoftWare to Abstract SoftWare
        this.software = software;
        this.software.env = this;
    }
    public void software_execute(){
        this.software.run();
    }
}

由於 software_install 方法在實現時,需要定義屬性 software 的屬性值,但對於 IHardWare,它並不知道 software 屬性的存在。

那麽要想編譯成功,我們就需要將接口改成 SoftWare 對象。但 interface 去依賴 ConcreteClass?這個並不合理。

沒辦法,只能選擇了 HardWare 不再實現接口——但這個實現在邏輯上是有意義的:我們面向接口編程,而 HardWare 不過是對接口的一種實現而已,我們無法保證抽象類是頂層接口,它的若幹實現並不一定具有普遍性——普遍性的依然是接口類。

my questions of C#