TL; DR: Попробуйте использовать Html.Partial
вместо Renderpage
Я получал Object reference not set to an instance of an object
, когда пытался сделать вид в представлении, отправив ему модель, например это:
@{
MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null
Отладка показала, что модель была Null внутри MyOtherView. Пока я не сменил его на:
@{
MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);
И это сработало.
Кроме того, причина, по которой я не имел Html.Partial
для начала, заключалась в том, что Visual Studio иногда выдает ошибки, (f9), если он находится внутри другого построенного цикла foreach
, хотя это не ошибка:
@inherits System.Web.Mvc.WebViewPage
@{
ViewBag.Title = "Entity Index";
List<MyEntity> MyEntities = new List<MyEntity>();
MyEntities.Add(new MyEntity());
MyEntities.Add(new MyEntity());
MyEntities.Add(new MyEntity());
}
<div>
@{
foreach(var M in MyEntities)
{
// Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
@Html.Partial("MyOtherView.cshtml");
}
}
</div>
Но я смог запустить приложение без проблем с этим " ошибка". Я смог избавиться от ошибки, изменив структуру цикла foreach
, чтобы выглядеть так:
@foreach(var M in MyEntities){
...
}
Хотя я чувствую, что это потому, что Visual Studio неправильно интерпретировала амперсанды и скобки .
Взято из стандарта C ++:
4.5 Интегральные рекламные акции [conv.prom] 1 Rvalue типа char, signed char, unsigned char, short int или unsigned short int может быть преобразовано на rvalue типа int, если int может представлять все значения типа источника; в противном случае исходное значение rvalue может быть преобразовано в rvalue типа unsigned int.
blockquote>На практике это означает, что все операции (по типам в списке) фактически оцениваются по типу
int
, если он может покрыть все значение, с которым вы имеете дело, иначе оно выполняется наunsigned int
. В первом случае значения сравниваются какunsigned int
, потому что один из них былunsigned int
, и поэтому -1 является «большим», чем 2. Во втором случае значения a, сравниваемые как целые числа со знаком, какint
, вся область какshort
, так иunsigned short
и т. д. меньше 2.(История вопроса: на самом деле все это сложное определение о покрытии всех случаев таким образом приводит к тому, что компиляторы могут фактически игнорировать фактический тип (!) :) и просто заботиться о размере данных.)
Когда вы используете арифметический оператор, операнды проходят через два преобразования.
Целочисленные акции: если int
может представлять все значения типа, то операнд продвигается до int. Это относится как к short
, так и к unsigned short
на большинстве платформ. Преобразование, выполняемое на этом этапе, выполняется на каждом операнде индивидуально, независимо от другого операнда. (Есть больше правил, но это тот, который применяется.)
Обычные арифметические преобразования: если вы сравниваете unsigned int
с signed int
, так как ни один из них не включает весь диапазон другого, и оба имеют одинаковый ранг, то оба они преобразуются в тип unsigned
. Это преобразование выполняется после изучения типа обоих операндов.
Очевидно, что «обычные арифметические преобразования» не всегда применяются, если не существует двух операндов. Вот почему существуют два набора правил. Например, один из них - это то, что операторы сдвига <<
и >>
не выполняют обычных арифметических преобразований, поскольку тип результата должен зависеть только от левого операнда (поэтому, если вы видите кого-то типа x << 5U
, тогда U
означает «ненужное»).
Разбивка: предположим, что типичная система с 32-битным int и 16-битным коротким.
int a = -1; // "signed" is implied
unsigned b = 2; // "int" is implied
if (a < b)
puts("a < b"); // not printed
else
puts("a >= b"); // printed
int
или unsigned int
, промо-акции не выполняются. int
не может представлять все возможные значения unsigned
, а unsigned
не может представлять все возможные значения int
, нет очевидного выбора. В этом случае оба преобразователя преобразуются в unsigned
. if (4294967295u < 2u)
, что является ложным. Теперь попробуем это с помощью short
:
short c = -1; // "signed" is implied
unsigned short d = 2;
if (c < d)
puts("c < d"); // printed
else
puts("c >= d"); // not printed
int
, они продвигаются до int
. int
, поэтому ничего не сделано. if (-1 < 2)
, что верно. Написание хорошего кода : Есть простой способ поймать эти «gotchas» в вашем коде. Просто всегда компиляция с включенными предупреждениями и исправление предупреждений. Я предпочитаю писать такой код:
int x = ...;
unsigned y = ...;
if (x < 0 || (unsigned) x < y)
...;
Вы должны следить за тем, чтобы любой код, который вы пишете, не запускался в другой подписанный vs. unsigned gotcha: signed overflow. Например, следующий код:
int x = ..., y = ...;
if (x + 100 < y + 100)
...;
unsigned a = ..., b = ...;
if (a + 100 < b + 100)
...;
Некоторые популярные компиляторы оптимизируют (x + 100 < y + 100)
до (x < y)
, но это история за другой день.
Сноска: обратите внимание, что если для
blockquote>int
подразумеваетсяsigned
,short
,long
иlong long
, это НЕ подразумевается дляchar
. Вместо этого это зависит от платформы.
Процесс преобразования для C ++ описывается как обычные арифметические преобразования . Тем не менее, я думаю, что наиболее релевантное правило находится в разделе подкатегории conv.prom: Интегральные рекламные акции 4.6.1 :
Значение целочисленного типа, отличного от bool, char16_t, char32_t или wchar_t, чей целочисленный ранг преобразования ([conv.rank]) меньше ранга int, может быть преобразован в prvalue типа int, если int может представлять все значения типа источника; в противном случае исходное значение prvalue может быть преобразовано в prvalue типа unsigned int.
blockquote>Самое смешное, что есть слово «can», которое, я думаю, предполагает, что эта акция выполняется по усмотрению компилятора.
Я также нашел этот фрагмент C-spec, который намекает на отсутствие продвижения:
11 EXAMPLE 2 In executing the fragment char c1, c2; /* ... */ c1 = c1 + c2; the ``integer promotions'' require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.
Существует также определение «ранга» . Список правил довольно длинный, но поскольку он применим к этому вопросу, «ранг» прост:
Ранг любого беззнакового целочисленного типа должен быть равен ранга соответствующего знакового целочисленного типа.
blockquote>