Что лучший способ состоит в том, чтобы хранить статические данные в C#, который никогда не будет изменяться

У меня есть класс, который хранит данные в asp.net 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? если не, что Вы рекомендовали бы?

5
задан John Farrell 25 May 2010 в 21:44
поделиться

8 ответов

Это кандидат на неизменяемую структуру, которая " выглядит как " перечисление: (Кроме того, я заметил, что вы использовали одно и то же значение id для двух из них, поэтому я исправил это ... Вы можете использовать следующее так же, как перечисление ...

PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote;

, и действительно приятно то, что этот подход не требует хранилища экземпляров, кроме 4-байтового целого числа (которое будет храниться в стеке, поскольку это структура). Все жестко запрограммированные значения хранятся в самом типе ... из которых только одно будет существовать для каждого домена приложения ...

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);       
} 
3
ответ дан 14 December 2019 в 13:28
поделиться

Глядя на ваш код, кажется, что вы просто пытаетесь создать набор объектов, которые на самом деле просто помещают перечисление PostVotePointValue в какой-то список. Т.е. у вас уже есть то, что вам нужно, только в самом перечислении. Я бы посоветовал вам не определять одну и ту же информацию в двух местах (это хранилище данных, которое вы запрашиваете, и перечисление). Я вижу, что это частая ошибка, которую делают люди. Они создают справочную таблицу / список, а затем создают перечисление, которое отражает строки таблицы, а это означает, что они должны изменить два места для любого изменения в списке.

Если 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));
        }
    }
}

Вы сможете адаптировать приведенное выше в подход, который предоставит вам список, который вы можете использовать для привязки данных, если вам это нужно.

1
ответ дан 14 December 2019 в 13:28
поделиться

По опубликованному вами фрагменту кода сложно сказать, раскрываете ли вы какие-либо данные за пределами класса.

Если нет, то это сработает. Однако в противном случае возникает несколько проблем:

  • Если вы открываете список, вы должны всегда возвращать его копию как IEnumerable , используя yield ключевое слово.
  • Убедитесь, что ваш PostVoteType неизменяемый, иначе ссылки могут быть изменены, а используемые поля могут быть изменены
1
ответ дан 14 December 2019 в 13:28
поделиться

«Никогда» - действительно очень трудное слово.

В вашем конкретном случае вы утверждаете, что не только ваши данные PostVoteType являются абсолютными и неизменяемыми, но также и коллекция контейнеров. Честно говоря, я не верю, что вы можете это знать, потому что вы не являетесь бизнесом (ваша интерпретация требований несовершена) и вы не экстрасенс (ваше знание будущего несовершенно).

Я бы посоветовал вам всегда хранить любые данные, которые не могут быть выражены в виде перечисления, в некотором репозитории. Там, где вы ожидаете реляционные и / или транзакционные и / или изменяемые потребности, это означает базу данных, если вы ожидаете высокого отношения чтения к записи, которое может быть файлом конфигурации (что, я считаю, должно быть в этом случае).

Редактировать: Что касается постоянства памяти, я согласен с другими, что кеш - лучшее место для хранения этого, или, скорее, в объекте домена, который поддерживается кешем.


Кроме того: ваша конструкция PostVoteTypes ужасна - настоятельно рекомендую вам выполнить рефакторинг:)

1
ответ дан 14 December 2019 в 13:28
поделиться

Если вам нужно часто обращаться к одним и тем же данным и не нужно хранить их в базовой базе данных, и эти данные примерно одинаковы во всех ситуациях, с которыми может столкнуться приложение, я предлагаю использовать кеширование. Кэширование рождается из этих требований. Кэширование обычно является самым быстрым способом предоставления данных, так как они всегда хранятся в памяти или в чем-то подобном для облегчения доступа приложения.

Вот хороший инструмент кэширования, входящий в состав Microsoft Enterprise Library , Caching Application Block .

Я думаю, что стоит потратить время на то, чтобы научиться эффективно его использовать.

0
ответ дан 14 December 2019 в 13:28
поделиться

Если он не меняется, к нему часто обращаются, и он одинаков для всех пользователей, то кэш .NET - подходящее место. Имейте свойство, которое выдает эти значения. Внутри свойство проверяет кэш на наличие этого списка и возвращает сохраненное значение; в противном случае оно создает его с нуля, добавляет в кэш и возвращает значение.

Это все равно, вероятно, должно быть настроено в базе данных, даже если вы сохраняете это в кэше. Я предполагаю, что вам нужно будет использовать это значение в сочетании с другими данными в вашей БД.

0
ответ дан 14 December 2019 в 13:28
поделиться

создать класс синглтонов.

-1
ответ дан 14 December 2019 в 13:28
поделиться

Мне интересно, почему вы не могли просто использовать для этого простое перечисление?

public enum PostVoteType
{
    UpVote = 0,
    DownVote = 1,
    SelectAnswer = 2,
    Favorite = 3,
    Offensize = 4,
    Spam = 5
}
1
ответ дан 14 December 2019 в 13:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: