Question

Dans VisualStudio (Pro 2008), je viens d’observer un comportement incohérent et je me suis demandé s’il existait un raisonnement logique derrière ce comportement.

Dans un projet WinForms, si j'utilise la ligne

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

Je reçois un avertissement du compilateur indiquant que je pourrais obtenir des "références involontaires possibles" car je compare le type objet au type MyObject. Assez juste.

Cependant, si j'utilise plutôt une interface pour comparer:

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

l'avertissement de compilation s'en va.

Est-ce que n'importe qui peut penser s'il y a une raison logique à cela ou juste un artefact du compilateur pour ne pas vérifier les interfaces pour les avertissements de comparaison. Des pensées?

MODIFIER Dans mon exemple, la liste déroulante était liée à une liste, mais cette liste avait été générée à l'aide de list<IMyInterface>.Cast<MyObject>().ToList<MyObject>()

C'est comme si le compilateur prenait encore en supposant que je me lie à la liste des IMyInterface.

(les méthodes d'objet et d'interface ont été modifiées pour protéger l'innocent)

Était-ce utile?

La solution

L'avertissement de compilation pour le premier exemple provient du fait que tout opérateur == personnalisé de votre classe serait ignoré et que les références seraient comparées (peut-être pas ce que vous vouliez, d'où l'avertissement).

Il n'est pas possible de spécifier qu'un opérateur doit être remplacé sur une interface. Par conséquent, toujours sera une comparaison de référence. L’avertissement n’est pas nécessaire car vous devez toujours vous y attendre.

Voici un exemple de substitution de l'opérateur ==:

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 est considérée égale si la propriété Key est égale. Si vous deviez créer une interface, vous ne pouvez pas spécifier qu’elle doit inclure un opérateur == personnalisé. Par conséquent, la comparaison sera toujours une comparaison de référence (et donc false dans le cas de notre exemple de code).

Autres conseils

Lagerdalek,

L'avertissement est généré car vous devez reconvertir l'élément de la collection Items dans le type d'origine lié à la zone de liste déroulante avant de comparer. sinon, vous pourriez obtenir des résultats inattendus, comme le prévient le compilateur.

Voici un exemple:

myComboBox.DataSource = Collection<Car>;

Ainsi, si la zone de liste déroulante est liée à une collection d'objets voiture , vous devez les rejeter avant la comparaison:

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

Dans ce cas, vous ne devriez recevoir aucun avertissement.

Une autre méthode que vous pouvez utiliser est la suivante:

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

Faites le moi savoir. Bonne chance! Je pars de mémoire, j'espère ne rien avoir mal écrit. : o)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top