Это плохая идея использовать массив с одним элементом вместо просто переменной?

#c# #arrays #performance

#c# #массивы #Производительность

Вопрос:

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

У меня есть базовый класс, из которого происходит множество других классов. Этот базовый класс предоставляет Value свойство типа object .

Теперь я должен также поддерживать многозначные версии большинства классов. Таким образом, я думал о том, чтобы изменить protected object value на protected object[] value и использовать массив, даже если требуется только одно значение.

Я знаю длину массива в конструкторе, поэтому в случае экземпляров с одним значением длина массива равна 1.

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

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

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

Отредактируйте, чтобы уточнить:

Цель базового класса в основном заключается в предоставлении интерфейса. Другие классы используют Value свойство, именно поэтому оно определено в базовом классе. Сама переменная была определена только в базовом классе, поэтому мне не нужно определять ее в каждом производном классе (тип всегда object).

Многозначное расширение требуется не потому, что существуют производные классы, которым требуется более одного значения, а потому, что будет контекстно-зависимая среда (не знаю, как сформулировать это лучше) и классам нужно запоминать значение для каждого контекста.

Например, думайте об этом как о методе итернационализации (не в моем случае, просто в качестве примера).

Класс представляет слово, и в зависимости от языка, Value это слово на соответствующем языке.

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

Надеюсь, это немного прояснит ситуацию.

Комментарии:

1. Я предлагаю вам не думать об этом, пока у вас действительно не возникнет проблема с производительностью. Смотрите также: Преждевременная оптимизация

2. Я не видел ничего, что заставляло бы меня подозревать снижение сложности сверх того, что для вас сделает вывод из Object . Какова цель / задача этого базового класса?

3. Базовый класс предоставляет множество функций, которые я не описал здесь, потому что я думал, что это не имеет отношения к вопросу. Он объявляет и предоставляет реализацию по умолчанию для нескольких событий, объявляет несколько абстрактных методов и т.д. Мне пришлось бы подробно описать всю систему, что, я думаю, не обязательно.

Ответ №1:

Нет: объем накладных расходов, безусловно, не был бы заметен. Если это уменьшает сложность кода, то это хорошая идея.

Комментарии:

1. Вопрос в том, хороший ли это дизайн, так что напрашивается только вопрос: как подобная база снижает сложность? Исходя из приведенной информации, я бы сказал, что на данный момент это, вероятно, увеличивает сложность

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

3. Сложность программного обеспечения не так субъективна, как принято считать. Дейкстра , Википедия ( случайное против существенного )

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

5. Существует множество операций, для которых требуется класс, производный от «базового класса», поэтому мне нужен только этот тип. Я не буду создавать 10 методов, которые делают то же самое, только с другим типом параметра. Таким образом, базовый класс и Value свойство, которое является одним из немногих свойств, необходимых для множества операций. Я бы «спрятал» массив от производных классов, чтобы они продолжали работать со Value свойством, не зная (или заботясь), являются ли они однозначными или многозначными. В случае многозначности только 1 значение за раз (а именно «текущее») должно представлять интерес для производных классов.

Ответ №2:

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

Ответ №3:

Это увеличивает накладные расходы, но я сомневаюсь, что это будет заметно при «нормальных» обстоятельствах (например, не в замкнутом цикле).

Ответ №4:

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

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

 public interface IValueProvider<out T> /* : IComparable<T>, IEquatable... etc */
{
    T Value { get; /*protected?*/ set; }
}
  

Если вы настаиваете, у вас могут быть помощники по реализации, например, так:

 public class ValueProviderClass<T> : IValueProvider<T> 
     where T : class, new()
{
     ValueProviderClass() { Value = new T(); }
}
  

Конечно, также структуры могут реализовать интерфейс, предоставляя еще больше возможностей для оптимизации производительности, если возникнет необходимость в будущем (однако типы значений не смогут прозрачно выводиться из «базового» valuetype, потому что среда CLR этого не допускает)

Обратите внимание на использование ковариации для обеспечения совместимости с IValueProvider, например

Надеюсь, эта идея поможет вам развить более рациональное мышление

Ответ №5:

Не видя вашего кода, у меня возникает ощущение, что можно поставить под сомнение дизайн. У вас есть базовый класс, который может содержать одно или несколько «значений» произвольного типа? Обычно я бы использовал базовый класс для содержания свойств и / или функциональности, которые являются общими для производных типов, но если я замечаю, что базовый класс пытается «соответствовать всем возможным потребностям» производных классов, вероятно, пришло время провести рефакторинг. В этом случае ваш базовый класс мне кажется слишком общим.

При этом возможно, что ваша конкретная ситуация оправдывает дизайн. (И я не думаю, что вы заметили бы какое-либо снижение производительности.)

Ответ №6:

Почему бы не сделать класс универсальным и не указать тип значения при создании экземпляра класса?