Другим случаем, когда NullReferenceExceptions
может случиться, является (неправильное) использование оператора as
:
class Book {
public string Name { get; set; }
}
class Car { }
Car mycar = new Car();
Book mybook = mycar as Book; // Incompatible conversion --> mybook = null
Console.WriteLine(mybook.Name); // NullReferenceException
Здесь Book
и Car
являются несовместимыми типами; a Car
не может быть преобразован / передан в Book
. Когда этот сбой завершается неудачно, as
возвращает null
. Используя mybook
после этого, вы вызываете NullReferenceException
.
В общем случае вы должны использовать cast или as
, как показано ниже:
Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:
ComicBook cb = (ComicBook)specificBook;
Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as
:
ComicBook cb = specificBook as ComicBook;
if (cb != null) {
// ...
}
Невозможно ответить на этот вопрос без полного понимания того, как каждая из этих упакованных записей используется в вашем коде приложения. Это то же самое, что и запрос «Должен ли я изменить это объявление переменной от Int64 до Byte?»
Не зная, какие значения, которые переменная будет ожидаться и которые необходимы для поддержания ответа, могут быть да. Или это может быть не так.
Аналогично в вашем случае. Если для записи требуется , она должна быть упакована в слева . Если это не нужно упаковывать, тогда нет никакого вреда, чтобы не упаковать его. Если вы не уверены или не можете сказать, тогда самый безопасный курс - оставить их такими, какими они есть.
В качестве руководства для принятия этого решения (если вы решите продолжить), ситуации, когда требуется упаковка документов или рекомендуется:
Это не обязательно исчерпывающий список, и все, что у них общего:
Что Я бы рекомендовал, чтобы (если это было возможно и практично) вы определяли, какая цель упаковки служит в каждом случае, и добавить документацию к этому ef fect к самому объявлению записи, так что кому-либо в будущем с тем же вопросом не нужно проходить этот процесс обнаружения, например ::
type
TSomeRecordType = packed record
// This record must be packed as it is used for persistence
..
end;
TSomeExternType = packed record
// This record must be packed as it is required to be compatible
// in memory with an externally defined struct (ref: extern code docs)
..
end;
Основная идея использования упакованных записей - not , что вы сохраняете несколько байтов памяти! Вместо этого речь идет об обеспечении того, чтобы переменные находились там, где вы ожидаете, что они будут в памяти. Без такой гарантии было бы невозможно (или, по крайней мере, трудно) управлять памятью вручную в куче, записывать и читать из файлов.
Следовательно, программа может работать неправильно, если вы распакуете " записи!
Если запись хранится / извлекается как упакованная или переданная каким-либо образом получателю, который ожидает ее упаковки, то не меняйте ее.
Обновление:
Там это тип строки, объявленный в вашем примере. Это выглядит подозрительно, поскольку сохранение записи в двоичном файле не будет сохранять содержимое строки.