2017-04-21 53 views
3

我只是想知道如果我有一個常量屬性,我可以設置一個公共屬性來封裝它嗎?封裝一個私有常量

例如

private const int DEFAULT_CHARGE = 200; 
public int default_charge 
{ 
    get { return DEFAULT_CHARGE; } 
} 

我沒有得到任何錯誤,但如果有東西是不變的,我真的不明白我們爲什麼封裝它的邏輯。我真的想明白這是爲什麼:

  1. 正確/錯誤
  2. 爲什麼這樣做?
  3. 好處?
+4

一個非常重要的原因是:編譯器可以(也會)在編譯它們的地方擴展常量。換句話說,改變值和分配一個新程序集不會導致客戶端在重新編譯之前真正使用新的值。有時候這就是你想要的,往往不是(其他時候它並不重要,因爲你不會替換單獨的程序集)。 –

回答

1

編譯器知道常量是內聯很重要。這意味着,這兩個例子導致相同的程序:

private const int DEFAULT_CHARGE = 200; 
public int default_charge 
{ 
    get { return DEFAULT_CHARGE; } 
} 

是與此相同,編譯後:

public int default_charge 
{ 
    get { return 200; } 
} 

正如你所看到的,參考DEFAULT_CHARGE正在編制後丟失。對於在多個項目中重複使用相同常量的解決方案,記住這一點非常重要。

讓我們假設在LibA和LibB中使用DEFAULT_CHARGE作爲public const。您的項目經理會告訴您將值從200更改爲300.本能地,您會去定義DEFAULT_CHARGE的LibA,將其更改爲300,然後僅重新編譯和部署LibA。

結果是,LibA現在使用300的新值,但LibB保持使用舊值200,因爲常量在編譯時被烘焙到DLL中。

你可能會封裝這個常量的原因是,你可以更容易地改變它的值。要求往往會隨着時間而改變。今天不變的值DEFAULT_CHARGE可能需要在將來由配置值替換。

通過封裝常量,您還可以防止我剛剛解釋的問題。如果LibA和LibB(以及LibX,LibY,LibZ,...)都依賴於封裝,則只需重新編譯和部署LibA即可在所有相關程序中設置默認收費。

+0

這是一個很明確的解釋,非常感謝! – lonewolf2288

1

即使某些東西是不變的,你仍然可以控制它是如何返回給調用者的。如果您有一個Double變量存儲到5個小數位,您可能希望將該值返回給調用方,並保留2位小數。封裝可以幫助您控制您的領域。

所以,你可能需要封裝恆定場這樣

private const double DEFAULT_CHARGE = 200.12345; 
    public int default_charge 
{ 
get { return Math.round(DEFAULT_CHARGE,2); } 
} 
1

您可能要實現interfaceabstract class等:

public interface IChargable { 
    int default_charge {get;} 
    } 

    public class MySimpleChargable: IChargable { 
    private const int DEFAULT_CHARGE = 200; 

    public int default_charge {get { return DEFAULT_CHARGE; }} 
    } 

您可以實現這樣的建設爲存根

Initial:

// Version 1.0 
    public class MyChargable { 
    private const int DEFAULT_CHARGE = 200; 

    //TODO: implement (rare) "some condition" case 
    public int default_charge {get { return DEFAULT_CHARGE; }} 
    } 

後來:

// Version 1.1 
    public class MyChargable { 
    private const int DEFAULT_CHARGE = 200; 

    public int default_charge { 
     get { 
     if (some condition) 
      return SomeComputation(); 

     return DEFAULT_CHARGE; 
     } 
    } 
+0

非常感謝!真的幫了 – lonewolf2288

0

這取決於你的需求。
一般而言,屬性被設計用於封裝所需的任何獲取/設置邏輯,甚至可計算值或常量。
在我看來,返回私有常量的值的公有屬性在架構方面很好,在這種情況下,使用你的代碼的人不知道他的工作常量是不變的,也就是說,他是從你的實現中抽象出來的,這很好。如果您決定做它不是一個常數,但配置的值,那麼你就不會將其暴露在你的庫消費,你只要把它想:

// private const int DEFAULT_CHARGE = 200; <-- is not used anymore 

public int DefaultCharge 
{ 
    get { return SomeSortOfFileOrDatabaseConfiguration.DefaultCharge; } 
} 

甚至

public int DefaultCharge 
{ 
    get 
    { 
     return CurrentUser.PersonalSettings.DefaultCharge; 
    } 
} 

這使得此代碼依賴於用戶的個人設置,而不會向客戶提供任何信息。

這是主要的好處。這完全是關於封裝和抽象。

但請使用適當的命名屬性 - 它應該是public int DefaultCharge,並注意Jeroen Mostert關於常量內聯的評論。

+0

你們是最棒的,非常感謝!我想我現在已經掌握了它的理論和基本原理!真的希望有一天我在你的水平! :) – lonewolf2288

0

據我所知,你可以創建一個公共訪問器來私有常量沒有問題。

  1. 你需要額外的邏輯加入到回報一樣以某種方式或其他價值格式化如果條件適用一個getter:

    時,您應該創建訪問一個常數。

  2. 您的常量是用作其他名稱空間庫的名稱空間的一部分,因爲如果您編譯常量所在的名稱空間,則相關名稱空間將只記住該常量的舊值,因爲它是在編譯時定義的。