2010-05-25 79 views
5

我有一個類,它存儲的數據在asp.net c#應用程序中永遠不會改變。我真的不想把這些數據放入數據庫 - 我希望它留在應用程序中。這裏是我的方式來存儲數據的應用程序:在C#中存儲靜態數據永遠不會改變的最佳方法是什麼

public class PostVoteTypeFunctions 
{ 
    private List<PostVoteType> postVotes = new List<PostVoteType>(); 
    public PostVoteTypeFunctions() 
    { 
     PostVoteType upvote = new PostVoteType(); 
     upvote.ID = 0; 
     upvote.Name = "UpVote"; 
     upvote.PointValue = PostVotePointValue.UpVote; 
     postVotes.Add(upvote); 

     PostVoteType downvote = new PostVoteType(); 
     downvote.ID = 1; 
     downvote.Name = "DownVote"; 
     downvote.PointValue = PostVotePointValue.DownVote; 
     postVotes.Add(downvote); 

     PostVoteType selectanswer = new PostVoteType(); 
     selectanswer.ID = 2; 
     selectanswer.Name = "SelectAnswer"; 
     selectanswer.PointValue = PostVotePointValue.SelectAnswer; 
     postVotes.Add(selectanswer); 

     PostVoteType favorite = new PostVoteType(); 
     favorite.ID = 3; 
     favorite.Name = "Favorite"; 
     favorite.PointValue = PostVotePointValue.Favorite; 
     postVotes.Add(favorite); 

     PostVoteType offensive = new PostVoteType(); 
     offensive.ID = 4; 
     offensive.Name = "Offensive"; 
     offensive.PointValue = PostVotePointValue.Offensive; 
     postVotes.Add(offensive); 

     PostVoteType spam = new PostVoteType(); 
     spam.ID = 0; 
     spam.Name = "Spam"; 
     spam.PointValue = PostVotePointValue.Spam; 
     postVotes.Add(spam); 
    } 
} 

當調用構造函數上面的代碼是運行。我有一些功能可以查詢上面的數據。但這是在asp.net中存儲信息的最佳方式嗎?如果不是,你會推薦什麼?

回答

3

這是一個不變的結構,一個候選人「看起來像」枚舉: (另外,我注意到你用相同的id值對於他們兩個,所以我固定的... 你可以使用下面就像你枚舉...

PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote; 

和真正的好處是,這種方法需要超過4個字節的整數(將被存儲在堆棧中的其他任何實例存儲,因爲它是一個結構)。所有硬編碼值都存儲在類型本身中,其中每個AppDomain只存在一個...

public struct PostVoteTypeFunctions 
{ 
    private int id; 
    private bool isDef; 
    private PostVoteTypeFunctions () { } // private to prevent direct instantiation 
    private PostVoteTypeFunctions(int value) { id=value; isDef = true; } 

    public bool HasValue { get { return isDef; } } 
    public bool isNull{ get { return !isDef; } } 
    public string Name 
    { 
     get 
     { return 
      id==1? "UpVote": 
      id==2? "DownVote": 
      id==3? "SelectAnswer": 
      id==4? "Favorite": 
      id==5? "Offensive": 
      id==6? "Spam": "UnSpecified"; 
     } 
    } 
    public int PointValue 
    { 
     get 
     { return // Why not hard code these values here as well ? 
      id==1? PostVotePointValue.UpVote: 
      id==2? PostVotePointValue.DownVote 
      id==3? PostVotePointValue.SelectAnswer: 
      id==4? PostVotePointValue.Favorite: 
      id==5? PostVotePointValue.Offensive: 
      id==6? PostVotePointValue.Spam: 
        0; 
     } 
    } 
    // Here Add additional property values as property getters 
    // with appropriate hardcoded return values using above pattern 

    // following region is the static factories that create your instances, 
    // .. in a way such that using them appears like using an enumeration 
    public static PostVoteTypeFunctions UpVote = new PostVoteTypeFunctions(1); 
    public static PostVoteTypeFunctions DownVote= new PostVoteTypeFunctions(2); 
    public static PostVoteTypeFunctions SelectAnswer= new PostVoteTypeFunctions(3); 
    public static PostVoteTypeFunctions Favorite= new PostVoteTypeFunctions(4); 
    public static PostVoteTypeFunctions Offensive= new PostVoteTypeFunctions(5); 
    public static PostVoteTypeFunctions Spam= new PostVoteTypeFunctions(0);  
} 
+0

我懷疑一個簡單的switch/case聲明平均而言會比使用鏈式三元運算符的性能稍微好一些,並且可讀性更高。 – 2010-05-27 13:23:08

+0

如果你在struct定義中定義了一個嵌套的私有枚舉,並用它替換int字段,這可以更好地工作。或者,在結構中定義一堆int常量,以便幻數構造函數,ifs和開關情況更具可讀性。 – 2010-05-27 13:26:29

+0

@Cameron,關於使用交換機的建議..不知道性能(通常,我只解決性能問題時的性能,但關於可維護性,可讀性和可擴展性等,Ternerys更簡潔,因此更具可讀性,以及更多的可擴展性(更少修改/重複)。本主題在這個論壇的其他帖子中大量討論。 – 2010-05-27 13:35:50

0

如果不改變,通常訪問,是對所有用戶都是相同的,那麼.NET緩存是適當的位置。有一個產生這些值的屬性。在內部,屬性檢查緩存中的這個列表並返回存儲的值;否則,它從頭開始構建它,添加到緩存中並返回值。

這應該仍可能在數據庫中配置但是,即使你緩存它。我想你需要將這些值與數據庫中的其他數據結合使用。

1

這是很難從您發佈您是否公開任何類的外部數據的代碼片段告訴。

如果不是,那麼這將工作。然而,如果沒有,有幾個問題:

  • 如果你暴露的列表,你應該永遠只使用yield關鍵詞返回一個副本作爲IEnumerable<PostVoteType>
  • 確保您PostVoteType是不可變的,否則引用可以更改和使用的領域可能會改變
1

「從不」是一個非常艱難的字確實如此。

你的具體情況您聲稱,不僅是你的PostVoteType數據絕對和一成不變的,但這樣是容器集合。坦率地說,我不相信你可以知道這一點,因爲你不是業務人員(你對需求的解釋是不完美的),而且你不是心理上的(你對未來的瞭解是不完美的)。

我建議你總是存儲任何不能表示爲某種存儲庫中的枚舉的數據。如果您期望讀寫比高,可以是配置文件(我相信這種情況應該是這樣),那麼您希望關係數據庫和/或事務性和/或可變需求意味着數據庫。

編輯:在存儲持久性方面與他人同意,高速緩存來存儲這些,或者說在由高速緩存支持的域對象的最佳場所。


旁白:你PostVoteTypes的建設是可怕的 - 強烈建議你要重構:)

+0

oh yay,隨機downvotes再 – annakata 2010-05-25 18:20:02

+0

它有什麼可怕的嗎?你會推薦什麼樣的重構? – 2010-05-25 18:20:08

+5

我見過的最糟糕的非答案之一。您對業務需求做出假設,然後根據您自己的未經證實的假設和不正當的偏見,對提出問題的人進行嚴厲批評。然後,你繼續不給任何答案。沒有我的downvote不是隨機的。 – 2010-05-25 18:21:29

0

當你需要經常訪問相同的數據,並且不需要將其存儲到底層數據庫,而且數據是關於在任何情況下的應用程序可能會遇到相同的,那麼我建議使用緩存。緩存是由這些需求產生的。緩存通常是提供數據的最快方式,因爲它們始終保存在內存中或類似於緩存,並使應用程序更容易訪問。

這是一個很好的緩存工具,提供Microsoft Enterprise LibraryCaching Application Block

我認爲值得花時間學習如何有效地使用它。

1

看看你的代碼,它看起來像你只是想創建一組對象,只是將枚舉PostVotePointValue放入某​​種列表。即你已經有了你需要在枚舉本身中定義的東西。我鼓勵你不要在兩個地方定義相同的信息(你要求的這個數據存儲和enum)。這是我看到人們犯的常見錯誤。他們創建一個查找表/列表,然後創建一個映射表的行的枚舉,這意味着他們必須修改兩個位置,以便對列表進行任何更改。

如果PostVotePointValue不是一個枚舉,而只是一些常量,或者如果有更多信息計劃打包,那麼這與此無關。

這裏有一個如何與枚舉爲「列表」從http://www.csharp-station.com/Tutorials/Lesson17.aspx

// iterate through Volume enum by name 
    public void ListEnumMembersByName() 
    { 
     Console.WriteLine("\n---------------------------- "); 
     Console.WriteLine("Volume Enum Members by Name:"); 
     Console.WriteLine("----------------------------\n"); 

     // get a list of member names from Volume enum, 
     // figure out the numeric value, and display 
     foreach (string volume in Enum.GetNames(typeof(Volume))) 
     { 
      Console.WriteLine("Volume Member: {0}\n Value: {1}", 
       volume, (byte)Enum.Parse(typeof(Volume), volume)); 
     } 
    } 

    // iterate through Volume enum by value 
    public void ListEnumMembersByValue() 
    { 
     Console.WriteLine("\n----------------------------- "); 
     Console.WriteLine("Volume Enum Members by Value:"); 
     Console.WriteLine("-----------------------------\n"); 

     // get all values (numeric values) from the Volume 
     // enum type, figure out member name, and display 
     foreach (byte val in Enum.GetValues(typeof(Volume))) 
     { 
      Console.WriteLine("Volume Value: {0}\n Member: {1}", 
       val, Enum.GetName(typeof(Volume), val)); 
     } 
    } 
} 

工作的一些例子你應該能夠將上述改編成的做法,會給你,你可以使用數據綁定,如果一個列表你需要它。

0

我很奇怪,爲什麼你不能只使用一個簡單枚舉這個?

public enum PostVoteType 
{ 
    UpVote = 0, 
    DownVote = 1, 
    SelectAnswer = 2, 
    Favorite = 3, 
    Offensize = 4, 
    Spam = 5 
} 
+0

那麼,如果upvote值得15分 - 我將如何將該點值放入枚舉中。這可能嗎?請告訴我。謝謝 – Luke101 2010-05-27 22:58:07

+0

你總是可以有一個靜態列表並做類似的事情。 var type = PostVoteType.UpVote; var points = new Dictionary (); var value = points [type]; – 2010-06-01 06:22:57

相關問題