Инициализация коллекции, чтобы пользователю не пришлось - PullRequest
4 голосов
/ 18 февраля 2009

Это может быть глупым вопросом, но есть ли распространенная практика инициализации свойств коллекции для пользователя, поэтому им не нужно создавать новую конкретную коллекцию перед ее использованием в классе?

Любое из них предпочтительнее другого?

Вариант 1:

public class StringHolderNotInitialized
{
    // Force user to assign an object to MyStrings before using
    public IList<string> MyStrings { get; set; }
}

Вариант 2:

public class StringHolderInitializedRightAway
{
    // Initialize a default concrete object at construction

    private IList<string> myStrings = new List<string>();

    public IList<string> MyStrings
    {
        get { return myStrings; }
        set { myStrings = value; }
    }
}

Вариант 3:

public class StringHolderLazyInitialized
{
    private IList<string> myStrings = null;

    public IList<string> MyStrings
    {
        // If user hasn't set a collection, create one now
        // (forces a null check each time, but doesn't create object if it's never used)
        get
        {
            if (myStrings == null)
            {
                myStrings = new List<string>();
            }
            return myStrings;
        }
        set
        {
            myStrings = value;
        }
    }
}

Вариант 4:

Есть ли другие хорошие варианты для этого?

Ответы [ 3 ]

10 голосов
/ 18 февраля 2009

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

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

2 голосов
/ 18 февраля 2009

Для варианта 1: если вы хотите заставить пользователя что-то инициализировать перед использованием вашего класса, тогда лучшее место для этого - в конструкторе.

Для варианта 2: если вы не принуждаете пользователя, вам действительно нужно самостоятельно инициализировать пустую коллекцию в конструкторе / инициализаторе.

Для варианта 3: Ленивая инициализация имеет смысл, только если она включает в себя слишком много работы или медленную / громоздкую операцию.

Мой голос идет за вариант 2.

1 голос
/ 18 февраля 2009

Единственная реальная причина использования решения для отложенной загрузки - оптимизация. И первое правило оптимизации - «не оптимизировать, если вы не измерили»:)

Исходя из этого, я бы выбрал решение с наименьшей вероятностью вызвать ошибку. В этом случае это будет решение № 2. Установка его в инициализаторе практически исключает вероятность нулевого реф здесь. Единственный способ, которым это произойдет, - если пользователь явно установит для него значение null.

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