Domanda

In VisualStudio (Pro 2008), ho appena notato alcuni comportamenti incoerenti e mi chiedevo se ci fosse qualche ragionamento logico dietro

In un progetto WinForms, se utilizzo la riga

if(myComboBox.Items[i] == myObject)

Ricevo un avviso del compilatore che potrei ottenere "Possibili riferimenti non intenzionali" mentre sto confrontando il tipo oggetto con il tipo MyObject.Abbastanza giusto.

Tuttavia, se utilizzo invece un'interfaccia per il confronto con:

if(myComboBox.Items[i] == iMyInterface)

l'avviso di compilazione scompare.

Qualcuno può pensare se esiste una ragione logica per cui ciò dovrebbe accadere, o solo un artefatto del compilatore per non controllare le interfacce per gli avvisi di confronto.qualche idea?

MODIFICARE Nel mio esempio, la casella combinata era associata a un elenco, ma tale elenco è stato generato utilizzando list<IMyInterface>.Cast<MyObject>().ToList<MyObject>()

È come se il compilatore stesse ancora assumendo che io sia vincolato all'elenco di IMyInterface.

(I metodi dell'oggetto e dell'interfaccia sono stati modificati per proteggere gli innocenti)

È stato utile?

Soluzione

L'avviso di compilazione per il primo esempio è dovuto al fatto che qualsiasi operatore == personalizzato per la tua classe verrebbe ignorato e i riferimenti verrebbero confrontati (forse non quello che volevi, da qui l'avviso).

Non è possibile specificare che un operatore debba essere sovrascritto su un'interfaccia, quindi lo farà Sempre essere un confronto di riferimento.L'avviso non è necessario perché dovresti sempre aspettartelo.

Ecco un esempio di sovrascrittura dell'operatore ==:

class Program
{
    static void Main(string[] args)
    {
        object t1 = new MyTest() { Key = 1 };
        MyTest t2 = new MyTest() { Key = 1 };

        Console.WriteLine((MyTest)t1 == t2); // Uses overriden == operator, returns true
        Console.WriteLine(t1 == t2); // Reference comparison, returns false
    }
}

public class MyTest
{
    public int Key { get; set; }

    public override bool Equals(object obj)
    {
        return this.Key == (obj as MyTest).Key;
    }

    public override int GetHashCode()
    {
        return this.Key.GetHashCode();
    }

    public static bool operator ==(MyTest t1, MyTest t2)
    {
        return t1.Equals(t2);
    }

    public static bool operator !=(MyTest t1, MyTest t2)
    {
        return !t1.Equals(t2);
    }

}

La classe MyTest è considerata uguale se la proprietà Key è uguale.Se dovessi creare un'interfaccia, non puoi specificare che includa un operatore == personalizzato e quindi il confronto sarebbe sempre un confronto di riferimento (e quindi falso nel caso del nostro codice di esempio).

Altri suggerimenti

Lagerdalek,

L'avviso viene generato perché è necessario eseguire nuovamente il cast dell'elemento dalla raccolta Items al tipo originale associato alla casella combinata, prima del confronto;altrimenti potresti ottenere risultati imprevisti come avvisa il compilatore.

Ecco un esempio:

myComboBox.DataSource = Collection<Car>;

Pertanto, se la casella combinata è associata a una raccolta di auto oggetti che vorresti riproporre prima del confronto:

if((car)myComboBox.Items[i] == thisCar)

Allora non dovresti ricevere nessun avviso.

Un altro metodo che potresti fare è:

using(myComboBox.Items[i] as car){
 if(myComboBox.Items[i] == thisCar)
}

Fammi sapere.Buona fortuna!Vado a memoria, spero di non aver sbagliato nulla.:o)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top