Статическое свойство - как правильно его инициализировать? - PullRequest
0 голосов
/ 27 сентября 2018

Я рефакторинг некоторого кода.В моем проекте много отчетов, в которых используются одни и те же данные.Например, каждый из них использует List<Product>, который извлекается из базы данных.

На данный момент у меня есть повторяющиеся строки, такие как:

var products = MyDatabase.Products.ToList(); 

Я хотел бы иметь статический класс со статическими свойствами, которые могут использовать мои отчеты.

Iхочу иметь заключительную строку в отчете что-то вроде:

var products = MyStaticClass.Products; 

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

Я читал об этом, и решения, кажется, следующие:

1)

public static List<Product> Products 
{
    get
    {
        return MyDatabase.Products.ToList(); 
    }
}

2)

public static List<Product> Products { get; set;} = MyDatabase.Products.ToList();

3)

public static List<Product> Products = MyDatabase.Products.ToList();

4)

private static  List<Product> _products;

public static List<Product> Products
{
    get 
    { 
        return _products ?? 
            ( _products = MyDatabase.Products.ToList()); 
    }
}

5.

private static Lazy<List<Product>> _products =
    new Lazy<List<Product>>(() => MyDatabase.Products.ToList());

public static List<Product> Products
{
    get { return _products.Value; }
}

Как я понял, первый случай вызывает MyDatabase.Products.ToList() каждый раз, когда я к нему обращаюсь,так что это не желаемое поведение.

Второй вариант почти такой же, как первый.Есть ли разница?Или просто более новая версия 1-го.

Третий вариант означает вызов этого MyDatabase.Products.ToList() только один раз, но он будет вызываться всегда, независимо от фактического использования.Близко, наверное.

4-й или 5-й вариант лучше, чем выше?Lazy<T> лучше всего использовать в моем случае?Будут ли загружаться данные только при вызове (если вызывается)?

Пожалуйста, уточните, правильно ли я понимаю эти опции, и предложите мне идеальное решение.

1 Ответ

0 голосов
/ 27 сентября 2018

Это худшее решение, которое вы когда-либо принимали: C # - это объектно-ориентированное программирование, и даже в других парадигмах это звучит как запах дизайна.

Итак, вы хотите поделиться некоторыми данными между многимиотчеты: как насчет внедрения зависимости?Создайте свои классы так, чтобы вы могли вводить эти общие данные:

public class Report 
{
     public Report(List<Product> products /* other arguments */) 
     {
           Products = products;
     }

     private List<Product> Products { get; }
}

Глобальное состояние - плохая идея, потому что ...

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

Кроме того, это билет на утечки памяти: эти ссылки живы для всего приложенияжизненный цикл.

Избегать глобального состояния: охватить внедрение зависимостей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...