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 неправильно интерпретировала амперсанды и скобки .
Для этого вам нужно __new__()
. (И вам также нужно сделать его классом нового стиля, предполагая, что вы используете Python 2, путем подкласса object
.)
class ClassA(object):
def __new__(cls,theirnumber):
if theirnumber > 10:
# all big numbers should be ClassB objects:
return ClassB.ClassB(theirnumber)
else:
# numbers under 10 are ok in ClassA.
return super(ClassA, cls).__new__(cls, theirnumber)
__new__()
выполняется как часть процесса создания класса до __init__()
. В основном __new__()
- это то, что на самом деле создает новый экземпляр, а затем __init__()
вызывается для инициализации его свойств. Вот почему вы можете использовать __new__()
, но не __init__()
, чтобы изменить тип созданного объекта: после запуска __init__()
объект уже создан, и слишком поздно менять его тип. (Ну ... не совсем, но это попадает в очень загадочную черную магию Python.) См. документацию .
В этом случае, однако, я бы сказал, что фабричная функция более вероятно, что-то вроде
def thingy(theirnumber):
if theirnumber > 10:
return ClassB.ClassB(theirnumber)
else:
return ClassA.ClassA(theirnumber)
. Кстати, обратите внимание, что если вы сделаете то, что я сделал с __new__()
выше, если возвращен ClassB
, метод __init__()
в ClassB
будет вызываться not ! Python только вызывает __init__()
, если объект, возвращенный из __new__()
, является экземпляром класса, в котором содержится метод __new__()
(здесь ClassA
). Это еще один аргумент в пользу подхода фабричной функции.
Не пытайтесь извратить назначение конструкторов: используйте заводскую функцию. Вызов конструктора для одного класса и возврат экземпляра другого класса - верный способ вызвать путаницу.
Я бы предложил использовать для этого шаблон фабрики. Например:
def get_my_inst(the_number):
if the_number > 10:
return ClassB(the_number)
else:
return ClassA(the_number)
class_b_inst = get_my_inst(500)
class_a_inst = get_my_inst(5)
self
как аргумент, и поэтому, что бы они ни переписывали в указанное имя, он не будет иметь никакого эффекта вне метода. (Вы можете, конечно, переустановить квалифицированные имена, такие какself.__class__
- квалифицированные имена и имена файлов полностью различаются почти во всех отношениях, о которых вы можете думать). – Alex Martelli 9 July 2010 в 03:27self.__class__
, является ошибкой реализации в CPython; официальная спецификация python говорит, что это не должно i> работать. Даже если это не случайность, это довольно ужасно. Короче: пожалуйста, не делайте этого, и особенно, пожалуйста, не предлагайте это другим людям. – habnabit 9 July 2010 в 05:52__class__ assignment works only if both classes have the same __slots__
(и поэтому, в частности, гарантируется работа, если ни один из классов не имеет__slots__
). Насколько я думаю, вы ошибочны в том, что вы заявляете как факт о том, что «это не должно работать», я думаю, что вы не в своем рокере, говоря «это довольно ужасная вещь»: это прекрасный метод, когда это необходимо (не часто). – Alex Martelli 9 July 2010 в 06:12