Симон Моурир дал этот пример :
object o = null;
DateTime d = (DateTime)o; // NullReferenceException
, где unboxing преобразование (литье) из object
(или из одного из классов System.ValueType
или System.Enum
или из типа интерфейса) - тип значения (кроме Nullable<>
) сам по себе дает NullReferenceException
.
В другом направлении конверсия бокса из a Nullable<>
, которая имеет HasValue
, равную false
, на ссылочный тип, может дать ссылку null
, которая затем может привести к NullReferenceException
. Классический пример:
DateTime? d = null;
var s = d.ToString(); // OK, no exception (no boxing), returns ""
var t = d.GetType(); // Bang! d is boxed, NullReferenceException
Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:
public static void MyExtension(this object x)
{
x.ToString();
}
следующий код будет проблематичным:
DateTime? d = null;
d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<>
экземпляров.
Вы делаете это хорошо, я не могу думать о лучшем способе, чем то, что вы делаете.
. Это способ, которым это можно сделать.
Самый эффективный способ, который вы можете сделать, несериализовать и получить данные, если вам нужно оптимизировать, не хранить все переменные, сериализованные.
Также всегда есть возможность проанализировать его с помощью регулярного выражения:)
Если вы не хотите дезарисовать все это (что может быть дорого, особенно для более сложных объектов), вы можете просто сделать strpos и искать нужные вам функции и извлечь их
Удивительно, если есть лучший способ.
blockquote>В примере, который вы приводите с массивом, я думаю, что все в порядке.
Если Сериализованная строка содержит данные и объекты, которые вы не хотите выполнять без инициализации (например, создание объектов, которые вы действительно не хотите), вы можете использовать сериализованную библиотеку PHP , которая является полным парсером для сериализованных данных.
Он обеспечивает статический доступ к сериализованным данным на низкоуровневом уровне, поэтому вы можете извлекать только подмножество данных и / или манипулировать сериализованными данными без их инициализации. Однако это слишком много для вашего примера, поскольку у вас есть только массив, и вам не нужно фильтровать / отличать слишком много, я думаю.
Я также думаю, что правильным способом является un-serialize.
Но другим способом может быть использование строковых операций, когда вы знаете, что хотите от массива:
$storedArray = 'a:2:{s:4:"test";s:2:"ja";s:6:"keyOne";i:5;}';
# another: a:2:{s:4:"test";s:2:"ja";s:6:"keyOne";s:3:"sdf";}
$split = explode('keyOne', $storedArray, 2);
# $split[1] contains the value and junk before and after the value
$splitagain = explode(';', $split[1], 3);
# $splitagain[1] should be the value with type information
$value = array_pop(explode(':', $splitagain[1], 3));
# $value contains the value
Теперь кто-то за бенчмарк? ;) Другим способом может быть RegEx ?
Конечно. Если вам нужен лучший способ - НЕ ИСПОЛЬЗУЙТЕ сериализованные массивы. Сериализация - это всего лишь транспортный формат, ОЧЕНЬ ограниченный.
Если вам нужен оптимизированный вариант - их сотни. Например, вы можете передать некоторую единую скалярную переменную вместо целого массива. И сразу же получите доступ к нему