2016-06-21 46 views
-1

我正在使用「奇怪值」來區分選項列表的第三方控件。他們使用兩種不同的屬性來唯一標識每個選項。使用靜態只讀與靜態獲取器模仿常量

Example: 
"Field" + "RW" = "CheckedOutBy" 
"System" + "N" = "Name" 
"Field + "N" = "Notifier" 

總共有37個不同的選擇(每個組合這兩個值組成37個獨特選項)。

我已經創建了一個存儲這兩個值的結構,並且我將爲每個選項創建一個新的結構實例。

public struct ColumnCode : IEquatable<ColumnCode> 
{ 
    public static readonly ColumnCode Empty = new ColumnCode(); 

    private readonly ColumnType _columnType; 
    private readonly string _code; 

    internal ColumnCode(ColumnType columnType, string code) 
    { 
     _columnType = columnType; 
     _code = code; 
    } 

    public override string ToString() { ... } 
    public bool Equals(ColumnCode other) { ... } 
    public override int GetHashCode() { ... } 
} 

理想我想創建爲每個選項的「常數」,但由於常量不是我想嘗試和模仿恆定的選項。

我提出的兩種方法是使用靜態只讀字段或靜態屬性只有一個getter。

public static class FieldOption 
{ 
    public static ColumnCode CheckedOutBy { get; } = new ColumnCode(ColumnType.Field, "XW"); 
    public static ColumnCode Name { get; } = new ColumnCode(ColumnType.System, "N"); 
    public static ColumnCode Notifier { get; } = new ColumnCode(ColumnType.Field, "N"); 
} 

public static class FieldOption 
{ 
    public static readonly ColumnCode CheckedOutBy = new ColumnCode(ColumnType.Field, "XW"); 
    public static readonly ColumnCode Name= new ColumnCode(ColumnType.System, "N"); 
    public static readonly ColumnCode Notifier = new ColumnCode(ColumnType.Field, "N"); 
} 

在任何情況下,現在可以參考我在我的C#代碼的選擇使用FieldOption.CheckedOutByFieldOption.NameFieldOption.Notifier等,但我不知道,如果一個方法是優於其他。

其中一個選擇比另一個更好地模仿const,還是有更好的方法,我不考慮。

我已經閱讀了大量的互聯網信息,我仍然沒有提出一個很好的答案。它似乎有些衝突。許多信息狀態偏好屬性而不是字段,但在本文中(https://msdn.microsoft.com/en-us/library/ms229057(v=vs.110).aspx)Microsoft說「DO使用公共靜態只讀字段用於預定義的對象實例」,所以我覺得靜態只讀字段是正確的選擇。

我也不確定這裏的反射如何影響比賽。我想確保FieldOptions的值不能改變,即使通過反射。

任何幫助,將不勝感激。

+0

你知道關鍵字的作用嗎? –

+0

@Jeroen Vannevel不知道我理解你的問題?我只是想知道如果C#編譯器處理這些不同?是否有性能優勢等 –

+0

一個是靜態的,另一個不是。一個是財產,另一個是領域。顯然,這些將會有所不同 - 決定你感興趣的差異取決於你。如果你的意思是*所有*差異,那麼最好的做法是閱讀文檔,看看靜態效應是什麼'和一個領域和財產如何不同。一旦你制定了更具體的問題,我們可以回答,而不是 –

回答

1

我想,以確保爲FieldOptions的值不能改變,甚至通過反射

來完成,這將是使用只讀屬性的唯一方法,而且當時只有你每次吸氣劑被調用時,如重新實例相應的值:

public static ColumnCode CheckedOutBy 
{ 
    get { return new ColumnCode(ColumnType.Field, "RW"); } 
} 

使用語法,你已經證明,或與私用二傳手自動性能,還有一個支持字段,並且支持字段尚可通過改變反射,儘管稍微有些困難,因爲字段名在源代碼中不可見並且具有依賴於編譯器實現的名稱。

當然,每次調用getter時重新實現這個值都會帶來負面的性能影響。因此,將該財產設置爲只讀(即免於反射)是有成本的。在你的情況下,這種性能成本是否重要是你自己必須確定的。對這個問題沒有「一個正確的答案」。

我已經在互聯網上閱讀了大量的信息,我還沒有提出一個很好的答案。其中一些似乎是衝突

這是因爲,除了你有一些特定的約束,通知你的決定(如想防止反射能夠改變價值)的情況下,這真的是主要是個人喜好的問題。 The previously proposed duplicate answer解決了區分領域和屬性的許多問題,但作爲您所問的特定場景中的實際問題,幾乎沒有真正的區別。

字段名義上性能更好,因爲它們可以直接訪問而不需要方法調用。但是a)在很多情況下,該方法的主體將被內聯,否定了這個優點,並且b)即使方法調用存在,在大多數情況下,重要性也不是很高。


所以,你需要決定:你需要防止代碼通過反射修改這些值有多嚴重?它是否真的很重要,足以讓值得用程序生成的值來包裝物業的價值?如果你這樣做,你多久會訪問這些屬性?每次調用getter時按需生成值的開銷會不會影響代碼的有用性?

這些只是你可以回答的問題。這裏的人不可能爲你回答這個問題。

+0

即使使用屬性getter,運行具有完全權限的代碼的人也可以簡單地編輯該成員的方法指針,更改調用該屬性getter時運行的代碼。從根本上說,根本沒有什麼*可以阻止某人在該機器上運行具有完全管理權限的任意代碼,特別是關於它自己的應用程序代碼。 – Servy

+0

@Servy:是的,的確如此。儘管如此,我認爲還有其他一些黑客行爲。 .NET提供了所有需要的工具來簡單地干擾字段的值,因此值得注意的是,防止與否的區別。沒有必要擔心無法阻止的攻擊者。 –

+0

你不能真正爭辯說某人會「意外地」去使用反射來修改私人支持字段的值,而沒有意識到他們不打算這樣做,並且確定的惡意用戶正在運行完整的特權代碼失敗的原因。這兩者之間確實沒有任何關係。 – Servy