SORU
8 NİSAN 2009, ÇARŞAMBA


Operatör Arayüzü Tabanlı C Programlama ile Aşırı yükleme#

Arka plan

Arayüz tabanlı geçerli bir proje ve operatörler (özellikle Eşitlik ve Eşitsizlik operatörleri) aşırı yükleme ne zaman bir sorun haline çalıştırmak programlama kullanıyorum.

< / ^ hr .

Varsayımlar

  • C# 3.0, .kullanıyorum NET ve Visual Studio 2008 3.5

GÜNCELLEŞTİRME, Aşağıdaki Varsayım Yanlış çıktı!

  • Tüm karşılaştırmalar kullanmayı gerektiren özellikle kütüphaneler (tahsilat gibi) türleri geçirmeden== kalıcı bir çözüm değil operatör yerine Eşittir.

Gerektiren endişeli olmamın sebebi== hiçbir yerde bulamadım bu operatör yerine kullanılacak Eşittir .Kullanım olacağını belirtti NET kurallar== ya da önermek operatör yerine Eşittir. Tekrar okuduktan sonra ancak Guidelines for Overriding Equals and Operator== bunu buldum:

Varsayılan olarak, = = iki başvuru aynı gösterip göstermediğini belirleyerek başvuru eşitliğini için test operatörü nesne. Bu nedenle, başvuru türleri, bu işlevselliği elde etmek için operatör == uygulamak zorunda değilsiniz. Ne zaman bir tür değişmez, yani veri bulunan bu örnek, değiştirilemez, aşırı operatör == karşılaştırılacak değer eşitlik yerine referans eşitlik yararlı olabilir, çünkü, gibi sabit nesneler, onlar olabilir aynı sürece onlar aynı değer. Operatör geçersiz kılmak için iyi bir fikir değildir olmayan değişmez türleri==.

ve bu 34**

İEquatable arabirimi genel koleksiyon nesneleri Sözlük gibi, adres bilgisi, Lastındexof, ve Kaldırmak İçerir gibi yöntemlerle eşitlik için test ederken Listesi ve LinkedList tarafından kullanılır. Genel bir koleksiyonu olabilecek herhangi bir nesne için uygulanmaması gerektiği.

< / ^ hr .

Kısıtlar

  • Herhangi bir çözüm beton türleri için kendi arabirimleri nesneleri döküm gerekir.

< / ^ hr .

Sorun

  • Operatör her iki== bir arayüz,== alttaki beton bu tür aşırı yöntem imzası ve böylece varsayılan maç olacak hiçbir operatör== yöntem çağrılır operatör Nesne.
  • Bir sınıf bir operatör, ikili operatörün en az bir parametre aşırı içeren türde olmalıdır, aksi takdirde derleyici bir hata (Hata BC33021 http://msdn.microsoft.com/en-us/library/watt39ff.aspx) oluşturulur
  • Olası bir arayüz üzerinde uygulama belirtmek için değil

Sorunu gösteren aşağıdaki Kodu ve Çıktısını görelim.

< / ^ hr .

Soru

Nasıl arayüz-temel programlama kullanırken sınıflar için uygun işleç aşırı sağlıyor musunuz?

< / ^ hr .

Referanslar

== Operator (C# Reference)

Önceden tanımlanmış bir değer türleri için eşitlik operatörü (==) eğer, basitçe değerleri eşit, false ise true değerini döndürür. Başvuru türleri dize dışında, == döndürür iki işlenen de true ise aynı nesneyi gösterecektir. String türü için == karşılaştırır dizeleri değerleri.

< / ^ hr .

Ayrıca Bkz

< / ^ hr .

Kod

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

< / ^ hr .

Çıktı

Address operator== overload called
Equal with both sides cast.

CEVAP
8 NİSAN 2009, ÇARŞAMBA


Kısa cevap: ikinci varsayım hatalı olabilir.Equals() kontrol etmek için doğru yoldursemantik eşitlikiki nesnelerin, operator ==.

Uzun cevap: operatörler için Aşırı çözümlemederleme zamanında yapılan, zaman çalışmaz.

Derleyici kesin bir operatör uygulayarak bu nesne türlerini biliyor sürece, derleme değil. Beri derleyici olamaz emin bir IAddress olacak bir şey vardır geçersiz kılmak için == tanımlanmış, düşüyor geri varsayılan operator == uygulama System.Object.

Bu daha net görmek için, Address operator bir tanımlamayı deneyin ve IAddress iki örneği de sözlerine ekledi.Açıkça Address dökme sürece derlemek için başarısız olur. Neden? Derleyici belli bir söyleyemem çünkü IAddress ** 15 System.Object geri düşmek için varsayılan operator uygulama yok.

Bölümü hayal kırıklığını muhtemelen kaynaklanıyor aslında Object uygulayan operator == ve her şey bir Object, yani derleyici olabilir başarıyla gidermek işlemleri gibi a == b tüm türleri. ==, bozdu zaman aynı davranışı görmeyi beklediğin ama yok, derleyici bulabilirsiniz en iyi maçı Object özgün bir uygulama olduğu için söylemedim.

Tüm karşılaştırmalar kullanmayı gerektiren özellikle kütüphaneler (tahsilat gibi) türleri geçirmeden== kalıcı bir çözüm değil operatör yerine Eşittir.

Benim görüşüme göre, bu senin yapman gereken bir şeydir.Equals() kontrol etmek için doğru yoldursemantik eşitlikiki nesne.Bazen anlamsal eşitlik sadece bu durumda herhangi bir değişiklik yapmanıza gerek kalmayacak referans eşitlik. Sizin örnekte olduğu gibi diğer durumlarda, başvuru eşitliğini daha güçlü bir eşitlik sözleşme ihtiyacın olduğunda Equals geçersiz kılar. Örneğin, eğer aynı VİN varsa Persons eğer aynı Sosyal Güvenlik numarası varsa eşit iki veya iki Vehicles eşit düşünebilirsiniz.

Ama Equals() operator == aynı şey değildir. operator ==, geçersiz kılmak için ihtiyacınız olduğunda Equals() ama neredeyse hiç tersi geçersiz kılmak. operator == sözdizimsel bir kolaylık daha. Bazı CLR dilleri (örneğin, Visual Basic.NET bile sana eşitlik operatörü geçersiz kılmak için izin vermez.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CareyHolzman

    CareyHolzman

    24 Ocak 2008
  • InsideBlackBerry

    InsideBlackB

    14 Aralık 2009
  • TopOfTheTech

    TopOfTheTech

    5 NİSAN 2010