Симон Моурир дал этот пример :
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<>
экземпляров.
Зависит от того, хотите ли вы перевернуть список на месте (т. е. изменить список) или нет. Никакой другой реальной разницы.
Часто использование reversed
приводит к более приятному коду.
Не зная реальной статистики о производительности, _list.reverse()
изменяет сам список, тогда как reversed(_list)
возвращает итератор, готовый пересечь список в обратном порядке. Это большая разница.
Если это не проблема, object.reverse()
кажется мне более читаемым, но, возможно, у вас есть определенные требования к скорости. И если reverse()
не принадлежит 80% программного обеспечения, потребляющего ресурсы, я бы не стал беспокоиться (как общее правило).
foo.reverse()
фактически меняет элементы в контейнере. reversed()
фактически ничего не отменяет, он просто возвращает объект, который можно использовать для итерации по элементам контейнера в обратном порядке. Если это то, что вам нужно, оно часто быстрее, чем наоборот.
Кажется, что есть большая разница. Я действительно думал, что все наоборот. Почему переупорядочивание значений в списке происходит быстрее, чем создание нового из итератора?
from decorators import bench
_list = range(10 ** 6)
@ bench
def foo():
list(reversed(_list))
@ bench
def bar():
_list.reverse()
foo()
bar()
print foo.time
print bar.time
0.167278051376 0.0122621059418
blockquote>