C # Проверка равенства для общей оболочки с неявным отрисовкой не работает для классов [duplicate]

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 неправильно интерпретировала амперсанды и скобки .

6
задан Jon Seigel 10 April 2010 в 20:00
поделиться

5 ответов

Оператор implicit работает только для назначения.

Вы хотите перегрузить оператор равенства (==) следующим образом:

class a
{
    public static bool operator ==(a x, b y)
    {
        return x == y.a;
    }

    public static bool operator !=(a x, b y)
    {
        return !(x == y);
    }
}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

Затем это должно разрешить вы сравниваете два объекта типа a и b, как было предложено в вашем сообщении.

var x = new a();
var y = new b();
bool c = (x == y); // compiles

Примечание:

Я рекомендую просто переопределить GetHashCode и Equals, как компилятор предупреждает, но поскольку вы, похоже, хотите их подавить, вы можете сделать это следующим образом.

Измените объявление класса a на:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}
13
ответ дан Community 23 August 2018 в 20:10
поделиться
  • 1
    и в этом случае выражение a == b будет скомпилировано без проблем. – Galilyou 21 May 2009 в 10:30
  • 2
    Это кажется правильным ответом. Приятно это понять. Только - я думаю, что перегрузка оператора в этом случае была бы излишней (она также требует перегрузки функции gethash () и equals (): /). – Arnis Lapsa 21 May 2009 в 10:30
  • 3
    Да, нет ограничений на определение или использование пользовательских (перегруженных) операторов по пользовательским типам. – Noldorin 21 May 2009 в 10:33
  • 4
    @Arnis L: К счастью, это только предупреждения. Вы можете переопределить их, если хотите (Equals могут иметь ту же логику, что и == и GetHashCode может просто вернуть a.GetHashCode () ^ b.GetHashCode ()), или вы можете игнорировать / подавлять предупреждения, если вам все равно. – Noldorin 21 May 2009 в 10:34
  • 5
    О, хорошо, я пропустил этот вопрос, извините. Я считаю, что это специфичная для компилятора функция (нет перегрузок операторов, определенных в System.Int32 или System.Double). В этом случае b (double) преобразуется в int перед приравниванием объектов того же типа. (Это может быть наоборот - простой тест скажет вам.) Надеюсь, это все имеет смысл для вас сейчас. – Noldorin 21 May 2009 в 11:09

http://msdn.microsoft.com/en-us/library/8edha89s.aspx

В каждом случае один параметр должен быть одного и того же типа как класс или структура, объявляющая оператор (...)

0
ответ дан A. M. 23 August 2018 в 20:10
поделиться

Возможно ли использовать оператор == на экземплярах разных типов, где можно неявно преобразовать в другое?

Да.

Что я пропустил?

Вот соответствующая часть спецификации. Вы пропустили выделенное слово.

Предопределенные операторы равенства ссылочного типа требуют [чтобы] оба операнда были значениями ссылочного типа или буквальным нулем. Кроме того, стандартное неявное преобразование существует из типа любого операнда в тип другого операнда.

Пользовательское преобразование по определению не является стандартным преобразованием. Это ссылочные типы. Поэтому предопределенный оператор равенства ссылочного типа не является кандидатом.

Если типы должны быть одним и тем же вызовом ==, то почему [double == int] работает?

Ваше предположение, что типы должны быть одинаковыми, неверно. Существует стандартное неявное преобразование из int в double, и есть оператор равенства, который принимает два удвоения, поэтому это работает.

Я думаю, вы также пропустили этот бит:

Ошибка времени компиляции использовать предопределенные операторы равенства ссылочного типа для сравнения двух ссылок, которые, как известно, различны во время компиляции. Например, если типы экземпляров типа компиляции являются двумя типами классов A и B, и если ни A, ни B не являются производными от другого, тогда было бы невозможно, чтобы оба операнда ссылались на один и тот же объект. Таким образом, операция считается ошибкой времени компиляции.

11
ответ дан Eric Lippert 23 August 2018 в 20:10
поделиться

Используйте этот параметр

 bool c = a.Equals(b);
0
ответ дан ole6ka 23 August 2018 в 20:10
поделиться
  • 1
    Это не будет полезно в конкретном случае, потому что я злоупотребляю шаблоном lambdas и builder для создания динамического набора свойств следующим образом: factory.Object.With (object = & gt; object.MyProp == newPropValue) .Create () – Arnis Lapsa 21 May 2009 в 10:28

Я бы предположил, что вам нужно на самом деле переопределить оператор == для типов, которые вас интересуют. Будет ли компиляция / время выполнения по-прежнему жаловаться, даже если типы являются конвертируемыми implicity, вам нужно поэкспериментировать.

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

В качестве альтернативы просто используйте реализации Equals, такие как ole6ka, и убедитесь, что реализация делает нужное вам применение.

1
ответ дан RobV 23 August 2018 в 20:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: