Другим случаем, когда 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) {
// ...
}
Если вы хотите избежать использования цикла for, это, вероятно, самый чистый способ сделать это:
indexCell = num2cell(indexmatrix, 1);
linearIndexMatrix = sub2ind(size(kDimensionalMatrix), indexCell{:});
finalTable = kDimensionalMatrix(linearIndexMatrix);
Первая строка помещает каждый столбец indexmatrix
в отдельные ячейки ячейки с использованием num2cell
. Это позволяет нам передавать все k
столбцы в виде списка разделенных запятыми в sub2ind
, функцию, которая преобразует индексы индексирования (строка , столбец и т. д.) в линейные индексы (каждый элемент матрицы пронумерован от 1 до N
, N
- общее число элементов в матрице). Последняя строка использует эти линейные индексы для замены цикла for. Хорошее обсуждение индексации матриц (нижний, линейный и логический) можно найти здесь здесь .
Тенденция чтобы уклониться от петель в пользу векторизованных решений, к чему привыкли многие пользователи MATLAB (включая меня). Однако более новые версии MATLAB обрабатывают цикл намного эффективнее. Как обсуждалось в , этот ответ на другой вопрос SO, использование для циклов может иногда приводить к более быстродействующему коду, чем вы могли бы получить с помощью векторизованного решения.
Я, конечно, НЕ говорю вы не должны пытаться больше векторизовать свой код, только чтобы каждая проблема была уникальной. Векторизация будет часто быть более эффективной, но не всегда . Для вашей проблемы скорость выполнения для циклов по сравнению с векторизованным кодом, вероятно, будет зависеть от того, насколько велики значения n
и k
.
Чтобы обрабатывать элементы вектора indexmatrix(row, :)
как отдельные индексы, вам нужны элементы в виде массива ячеек. Итак, вы можете сделать что-то вроде этого
subsCell = num2cell( indexmatrix( row, : ) );
finalTable( row ) = kDimensionalMatrix( subsCell{:} );
Чтобы развернуть subscell как список, разделенный запятыми, вам, к сожалению, нужны две отдельные строки. Однако этот код не зависит от k
.
n
строки из indexmatrix
сразу.
– Shai
5 December 2012 в 18:19
Преобразуйте свои подиндексы в линейные индексы хакерским способом
ksz = size(kDimensionalMatrix);
cksz = cumprod([ 1 ksz(1:end-1)] );
lidx = ( indexmatrix - 1 ) * cksz' + 1; #'
% lindx is now (n)x1 linear indices into kDimensionalMatrix, one index per row of indexmatrix
% access all n values:
selectedValues = kDimensionalMatrix( lindx );
Приветствия!