簡體   English   中英

在C#中實現全局常量的最佳方法是什么?

[英]What's the best way to implement a global constant in C#?

我有一個Common項目,我在其中添加了QueryStringNames的公共常量。

我知道一般常量應該是內部的或私有的,但我需要公共常量,因為我想允許全局訪問查詢字符串名稱,會話密鑰等。

我知道有3種解決方案,但它們都有一個重要的問題。 調用程序集將包含my常量的副本,這意味着如果我必須更改常量值,我將必須編譯我的Common程序集和調用程序集程序!

1) public const string ConstName = "a value";
2) public readonly string ConstName = "a value";
3) To be stored in a public resource file.

除了將它們存儲在web.config文件(沒有intellisense)之外,在C#中定義公共常量的最佳方法是什么?

這取決於。 如果它真的是一個不會改變的常量,即使在你的代碼的未來版本中,那么const也沒問題。 否則請使用static readonly字段。

const將嵌入到調用程序集中,而對於static readonly ,調用程序集僅包含對該字段的引用。 這意味着const需要在更改值時重新編譯所有相關代碼,而public readonly使用新值,即使不重新編譯調用程序集也是如此。

如果要將“常量”存儲在配置文件中,但是像Intellisense一樣,則可以使用不帶公共設置器的屬性。 然后在運行時從配置文件中填充它。 但我認為配置值首先不應該是static的。 對於配置值,我會使用某種單例,最好是IoC變體,而不是Class.Instance變體。 所以我只需要定義如下界面:

interface IMyConfig
{
  string Key{get;}
}

並且需要此配置的類將其作為構造函數參數:

public MyClass(IMyConfig config)
{
    ...
}

如果你認為你要改變它並且你擔心必須編譯它,那么為什么不在web配置文件中使用appSettings? 這就是它的用途。 如果你真的需要intellisense,那么你可以將一個類放在一個讀取配置值的程序集中,並將其公開為一個屬性,以便於引用。 如果它是敏感數據,那么我不會把它放在配置文件中,我只是編譯它,因為你不想妥協你的應用程序。

<appSettings>
    <add key="myconstant" value="here's the value!" />
</appSettings>

這是引用該值的類,它為您提供智能感知,能夠在將來輕松更改它,而無需重新編譯任何內容

public class MyAppConfigSettings
{
    public string MyConstant { get; private set; }

    public MyAppConfigSettings()
    {
        MyConstant = ConfigurationManager.AppSettings["myconst"];
    }
}

它可能不是您的解決方案的答案,但它可能會給您一些其他的想法。

如果你正在激活fxCop(Visual Studio發行版中包含的代碼分析工具),你可能會因為改變常量而成為:

public static readonly string ConstName =“a value”;

我不確定我是否完全理解了這個問題...你是否要求一個解決方案來存儲一些全局變量,這些變量不會導致重新編譯到引用那些全局變量的程序集,如果你改變它們? 如果是這樣,為什么不嘗試按照控制反轉原理重新設計您的架構呢? 想“不要打電話給我們,我們會打電話給你”好萊塢原則。 如果需要某個const的所有程序集只調用一個接口(它們擁有),它接受一個具有所需值的屬性,然后你有一個實現這些接口的常量項目(通過引用那些項目然后實現這些接口)那么當你改變常量的值時,那些項目永遠不需要重新編譯。

無論如何我確定你知道它們,但是讀了SOLID原則 ,“D”是依賴性倒置原理(控制反轉)。 我認為考慮到你的擔憂(假設我已經理解你了),他們可以真正幫助你。

控制反轉的一個例子可以簡單到:

MyService.dll:

public class MyService
{

    // injected dependency
    public IMyConstants MyConstants { get; set; }

    public MyMethod(){

        // get your query...
        var query = IMyConstants.Query;
    }

}

MyConstants.dll:

public MyConstants : IMyConstants {

    // implementation of query property from the myservices.dll interface
    public string Query { ... }

}

所以myconstants.dll引用myservice.dll而不是相反(意味着myservices不需要重新編譯)。 然后,引導代碼(將其全部設置並注入依賴關系)存在於其他地方。

對不起,如果我誤解了你,希望有幫助!

在大多數情況下,我更喜歡第二個選項,因為它不會導致問題(通過復制值到其他程序集)。 速度可能比常數慢,但這種納秒速度還不成熟。

您可以使用Cache對象並在Global.asax中定義它們

如前所述,情況並非如此:

  • const:是有效的,除非重新編譯,否則無法修改。
  • readonly:該值在聲明或構造函數中初始化,並在之后保持只讀。

當字段聲明包含只讀修飾符時,聲明引入的字段的賦值只能作為聲明的一部分或在同一個類的構造函數中出現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM