Sobrecarga de operador com programação baseada em interface em C #

Fund

Estou usando programação baseada em interface em um projeto atual e tive um problema ao sobrecarregar os operadores (especificamente os operadores de Igualdade e Desigualdade

Premissa Estou usando C # 3.0, .NET 3.5 e Visual Studio 2008

UPDATE - A seguinte suposição era falsa!

Exigir que todas as comparações usem Equals em vez de operator == não é uma solução viável, especialmente ao passar seus tipos para bibliotecas (como Coleções

O motivo pelo qual eu estava preocupado em exigir que o Equals fosse usado em vez do operador == é que não consegui encontrar em nenhum lugar nas diretrizes do .NET que ele declarasse que usaria o Equals em vez do operador == ou até sugerisse. No entanto, após reler Diretrizes para substituir iguais e operador == Encontrei o seguinte:

Por padrão, o operador == testa a igualdade de referência, determinando se duas referências indicam o mesmo objeto. Portanto, os tipos de referência não precisam implementar o operador == para obter essa funcionalidade. Quando um tipo é imutável, ou seja, os dados contidos na instância não podem ser alterados, sobrecarregar o operador == para comparar a igualdade de valor em vez da igualdade de referência pode ser útil porque, como objetos imutáveis, eles podem ser considerados os mesmos desde que como eles têm o mesmo valor. Não é uma boa idéia substituir o operador == em tipos não imutáveis.

e isto Interface Equipável

A interface IEquatable é usada por objetos genéricos de coleção, como Dictionary, List e LinkedList, ao testar a igualdade em métodos como Contains, IndexOf, LastIndexOf e Remove. Ele deve ser implementado para qualquer objeto que possa ser armazenado em uma coleção genéric

Contraints Qualquer solução não deve exigir a conversão dos objetos de suas interfaces para seus tipos de concretProblem Sempre que os dois lados do operador == forem uma interface, nenhuma assinatura do método de sobrecarga do operador == dos tipos de concreto subjacentes corresponderá e, portanto, o método padrão do operador de Objeto == será chamado. Ao sobrecarregar um operador em uma classe, pelo menos um dos parâmetros do operador binário deve ser o tipo que contém, caso contrário, um erro do compilador é gerado (Erro BC33021http: //msdn.microsoft.com/en-us/library/watt39ff.asp) Não é possível especificar a implementação em uma interface

Veja o código e a saída abaixo demonstrando o problem

Questã

Como você fornece sobrecargas de operador adequadas para suas classes ao usar a programação baseada em interface?

Referência

== Operador (referência de C #)

Para tipos de valor predefinidos, o operador de igualdade (==) retornará true se os valores de seus operandos forem iguais, caso contrário, false. Para tipos de referência diferentes de string, == retorna true se seus dois operandos se referem ao mesmo objeto. Para o tipo de string, == compara os valores das strings.

Veja tambéCódig
using System;

namespace OperatorOverloadsWithInterfaces
{
    public interface IAddress : IEquatable<IAddress>
    {
        string StreetName { get; set; }
        string City { get; set; }
        string State { get; set; }
    }

    public class Address : IAddress
    {
        private string _streetName;
        private string _city;
        private string _state;

        public Address(string city, string state, string streetName)
        {
            City = city;
            State = state;
            StreetName = streetName;
        }

        #region IAddress Members

        public virtual string StreetName
        {
            get { return _streetName; }
            set { _streetName = value; }
        }

        public virtual string City
        {
            get { return _city; }
            set { _city = value; }
        }

        public virtual string State
        {
            get { return _state; }
            set { _state = value; }
        }

        public static bool operator ==(Address lhs, Address rhs)
        {
            Console.WriteLine("Address operator== overload called.");
            // If both sides of the argument are the same instance or null, they are equal
            if (Object.ReferenceEquals(lhs, rhs))
            {
                return true;
            }

            return lhs.Equals(rhs);
        }

        public static bool operator !=(Address lhs, Address rhs)
        {
            return !(lhs == rhs);
        }

        public override bool Equals(object obj)
        {
            // Use 'as' rather than a cast to get a null rather an exception
            // if the object isn't convertible
            Address address = obj as Address;
            return this.Equals(address);
        }

        public override int GetHashCode()
        {
            string composite = StreetName + City + State;
            return composite.GetHashCode();
        }

        #endregion

        #region IEquatable<IAddress> Members

        public virtual bool Equals(IAddress other)
        {
            // Per MSDN documentation, x.Equals(null) should return false
            if ((object)other == null)
            {
                return false;
            }

            return ((this.City == other.City)
                && (this.State == other.State)
                && (this.StreetName == other.StreetName));
        }

        #endregion
    }

    public class Program
    {
        static void Main(string[] args)
        {
            IAddress address1 = new Address("seattle", "washington", "Awesome St");
            IAddress address2 = new Address("seattle", "washington", "Awesome St");

            functionThatComparesAddresses(address1, address2);

            Console.Read();
        }

        public static void functionThatComparesAddresses(IAddress address1, IAddress address2)
        {
            if (address1 == address2)
            {
                Console.WriteLine("Equal with the interfaces.");
            }

            if ((Address)address1 == address2)
            {
                Console.WriteLine("Equal with Left-hand side cast.");
            }

            if (address1 == (Address)address2)
            {
                Console.WriteLine("Equal with Right-hand side cast.");
            }

            if ((Address)address1 == (Address)address2)
            {
                Console.WriteLine("Equal with both sides cast.");
            }
        }
    }
}
Resultad
Address operator== overload called
Equal with both sides cast.

questionAnswers(2)

yourAnswerToTheQuestion