Question

Une partie du code pour le contexte:

class a
{

}

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

  a a=null;
  b b=null;
  a = b;

  //compiler: cannot apply operator '==' to operands of type tralala...
  bool c = a == b; 

Est-il possible d'utiliser == opérateur sur différentes instances de type, où l'on peut convertir implicitement à l'autre? Qu'est-ce que j'ai raté?

Edit: Si les types doivent être le même appel ==, alors pourquoi

int a=1;
double b=1;
bool c=a==b; 
œuvres

Était-ce utile?

La solution

L'opérateur implicit ne fonctionne que pour l'affectation.

Vous voulez surcharger l'opérateur d'égalité (de ==), en tant que tel:

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;
    }
}

Cela devrait vous permettre de comparer deux objets de type a et b comme suggéré dans votre message.

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

Remarque:

Je recommmend remplaçant simplement la méthode GetHashCode et Equals, comme le compilateur met en garde, mais comme vous semblez vouloir les supress, vous pouvez le faire comme suit.

Changer votre déclaration de classe de a à:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}

Autres conseils

  

Est-il possible d'utiliser == opérateur   différentes instances de type, où l'on   peut implicitement convertir à une autre?

Oui.

  

Qu'est-ce que je manque?

Voici la partie pertinente de la spécification. Vous avez manqué le mot mis en surbrillance.

  

L'égalité de type référence prédéfinie   les opérateurs ont besoin [que] les deux opérandes   sont des valeurs ou du type de référence   null littéral. En outre, une norme   existe conversion implicite de la   type d'opérande soit le type de   l'autre opérande.

Une conversion définie par l'utilisateur est, par définition, pas une conversion standard. Ce sont des types de référence. Par conséquent, l'opérateur d'égalité de type référence prédéfinie n'est pas un candidat.

  

Si les types doivent être le même appel ==,   alors pourquoi [double == int] fonctionne?

Votre supposition que les types doivent être identiques est incorrect. Il existe une norme implicite de conversion int en double et il y a un opérateur d'égalité qui prend deux doubles, donc cela fonctionne.

Je pense que vous aussi avez manqué ce bit:

  

Il est une erreur de compilation pour utiliser la   égalité de type référence prédéfinie   opérateurs de comparer deux références   qui sont connus pour être différent à   la compilation. Par exemple, si le   types à la compilation des opérandes sont   deux types de classe A et B, et si   ni A ni B dérive de la   d'autre part, il serait alors impossible   les deux opérandes pour référencer le même   objet. Ainsi, l'opération est   considéré comme une erreur de compilation.

Je suppose que vous devez remplacer réellement l'opérateur == pour les types qui vous intéressent. Que la compilation / exécution se plaindra encore, même si les types sont quelque chose convertable implicitement que vous aurez à expérimenter.

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);
        }
    }

Vous pouvez simplement utiliser Equals implémentations comme ole6ka suggère et veiller à ce que la mise en œuvre fait la coulée de type dont vous avez besoin.

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

  

Dans chaque cas, un paramètre doit être   du même type que la classe ou struct   qui déclare l'opérateur (...)

Utilisez cette

 bool c = a.Equals(b);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top