C# - Как я могу удостовериться, что все мои структуры инициализируются?

говорит, что передача массива char с нулевым символом в конце в std :: strlen является неопределенным поведением

Правильно.

Однако приведенный ниже код работает просто отлично.

Все строки имеют значение с нулевым завершением и поэтому не имеют неопределенного поведения.

Несмотря на это, вы не можете предположить, что программа с неопределенным поведением не будет работать "отлично". В этом нет ничего необычного.

и, скорее всего, приведет к сбою программы.

Не стоит ожидать, что неопределенное поведение "может вызвать сбой программы". UB вполне может не вызвать сбой программы.

6
задан mackenir 6 December 2008 в 21:48
поделиться

5 ответов

Я не думаю, что C# позволяет Вам создавать конструкторов по умолчанию на типах значения. Существует несколько вопросов, связанных с Вашей проблемой:

Существует способ сделать, он в IL, но инициализировать массивы все еще не вызовет этих конструкторов.

2
ответ дан 9 December 2019 в 20:50
поделиться

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

Если Вы хотите, чтобы начальное значение Точности было-1, Вы могли бы реализовать свойство Accuracy, таким образом это, когда базовое поле == 0, свойство возвращается-1.

Одна возможность:

struct Value
{
  int _accuracyPlusOne;

  public int Accuracy
  { 
    get { return _accuracyPlusOne - 1; }
    get { _accuracyPlusOne= value + 1; }
  }
}
3
ответ дан 9 December 2019 в 20:50
поделиться

Вы не можете избавиться от конструктора по умолчанию (Jon Skeet, конечно, ответил, почему очень хорошо в том, Почему я не могу определить конструктора по умолчанию для структуры в.NET?), но Вы могли создать класс фабрики, который позволяет Вам определять свои значения структуры с правильно инициализированными параметрами. Вы могли использовать модульные тесты с, дразнят/проверяют, чтобы удостовериться, что, когда новая стоимость создается Вашим кодом, они используют фабрику. Это было бы конвенцией, которую необходимо будет осуществить, поскольку компилятор не осуществит ее для Вас.

public static class StructFactory
{
    public static Value DefaultValue()
    {
         Value v = new Value();
         v.Value = 0.0;
         v.Accuracy = 15; /* digits */
         return v;
    }
}

...

Value v = StructFactory.DefaultValue();
3
ответ дан 9 December 2019 в 20:50
поделиться

Почему Вы не можете определить явного конструктора? Это - то, для чего они. Кроме того, почему Вы думаете, что "не можете позволить себе выделение "кучи""? Выделение "кучи" является очень дешевым на управляемых языках. Как Вы протестировали это предположение, что Вы не можете позволить себе выделение "кучи", или действительно что выделение "кучи" является более дорогим во-первых?

(Для типа, состоящего из "двойного и нескольких параметров", я подозреваю, что Вы бодрствуете в размере, где выделение "кучи" является на самом деле более дешевым и более эффективным),

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

Но конечно, у Вас нет гарантий, что люди на самом деле называют его.

Править: Выделение "кучи" в.NET в основном состоит из просто простой операции нажатия стека. Это - хорошая вещь об управляемом (и собрал "мусор"), языки. Время выполнения по существу использует большой стек в качестве своей "кучи", таким образом, каждое выделение просто увеличивает указатель вершины стека немного (после того, как проверка, что существует достаточно свободной памяти, конечно). Сборщик "мусора" затем заботится об уплотнении памяти при необходимости.

Таким образом, само выделение "кучи" является смехотворно дешевым. Конечно, дополнительное давление GC могло бы замедлить Вас снова (Хотя насколько я знаю, время, требуемое для передачи GC, зависит только от количества живого объекта, не на тех, чтобы быть GC'ed, также - бесчисленные "мертвые" объекты, лежащие вокруг, не могут быть большой проблемой), но с другой стороны, выделение стека не является бесплатным также. Типы значения передаются значением, таким образом, каждый раз Вы передаете свой тип в качестве параметра функции или возвращаете его, копия должна быть сделана. Я не знаю, насколько большой Ваше значение, но двойными составляют 8 байтов, и, учитывая, что у Вас есть несколько дополнительных параметров, я приму 32 байта. Это могло бы быть столь большим, что дополнительное копирование, требуемое для valuetypes, делает его медленнее чем при использовании выделения "кучи". Возможно.

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

4
ответ дан 9 December 2019 в 20:50
поделиться

Вы надеетесь инициализировать точность к-1 с конструктором по умолчанию? Я не думаю, что можно мешать кому-то использовать new Value(), но Вы могли добавить конструктора, который позволяет Вам использовать new Value(10) и имейте точность, инициализировал способ, которым Вы хотите.

Посмотрите страницу MSDN о [Конструкторы Структуры] (http://msdn.microsoft.com/en-us/library/aa288208 (По сравнению с 71) .aspx).

Вы могли всегда выдавать исключение в коде, который использует Вашу структуру, если Вы встречаетесь с точностью 0 (если то значение никогда не имеет смысл!).

0
ответ дан 9 December 2019 в 20:50
поделиться
Другие вопросы по тегам:

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