чаму раўняецца не працуе так жа, калі элементы адлітыя на аб'ект?

калі я кінуў Int і паплавок аб'екта і параўнаць іх роўнасць заўсёды фальшыва. Чаму?

        float f = 0.0f;
        int i = 0;
        Console.WriteLine(f.Equals(i));//true
        Console.WriteLine(i.Equals(f));//false
        Console.WriteLine(i == f);//true
        Console.WriteLine("----------------");
        object obf = f;
        object obi = i;
        Console.WriteLine(obf.Equals(obi));//false
        Console.WriteLine(obi.Equals(obf));//false
        Console.WriteLine(obi == obf);//false
        Console.WriteLine("----------------");

абнаўленне: гэта не так для таго ж тыпу

        int i1 = 1;
        int i2 = 1;
        object oi1 = i1;
        object oi2 = i2;
        Console.WriteLine(oi1.Equals(oi2));//true
        Console.WriteLine(oi2.Equals(oi1));//true
6

8 адказы

А паплавок роўны толькі іншаму флоат , і Int роўны толькі іншаму Int . Адзіныя лініі, якія вяртаюцца True гэтыя з іх:

Console.WriteLine(f.Equals(i));
Console.WriteLine(i == f);

У абодвух гэтых выпадках, ёсць невідавочнае пераўтварэнне значэння я у флоат , таму яны эквівалентныя:

Console.WriteLine(f.Equals((float) i));
Console.WriteLine((float) i == f);

Гэтыя пераўтварэнні з'яўляюцца толькі нармальныя пераўтварэнні, неабходныя для дазволу перагрузкі метадаў і аператараў.

Ні адзін з астатніх радкоў не звязана, што невідавочнае пераўтварэнне, таму яны параўнанне двух розных тыпаў, што дае вынік False , нават калі ён з'яўляецца Параўнанне па кошту ( што ў выпадку з усімі Роўна выклікі). Вось чаму, выкарыстоўваючы Роўна на скрынкавай Int значэння робіць вяртанне True , таму што гэта параўнанне двух значэнняў аднаго і таго ж тыпу значэнне .

У гэтым выпадку:

Console.WriteLine(obi == obf);

ён нават не спрабуе параўноўваць лікавыя значэння - гэта параўнанне спасылкі для адзінкавых аб'ектаў. Паколькі існуюць дзве розныя спасылкі, вынік хлусня - і будзе, нават калі абодва значэння былі тыпу Int .

10
дададзена
@CharlesLambert: Так. Паглядзіце на IL, і вы ўбачыце, што яна выконваецца.
дададзена аўтар Jon Skeet, крыніца
робіць невідавочнае пераўтварэнне атрымаць апрацоўваюцца падчас кампіляцыі?
дададзена аўтар Charles Lambert, крыніца

Іншыя ўжо патлумачылі, чаму == не працуе, як чакаецца, на вашых аб'ектах.

Што тычыцца праўку: oi1.Equals (oi2) працуе, таму што Роўна віртуальная функцыя і, такім чынам, Int32.Equals (аб'ект) называецца, чыё вяртаецца значэнне вызначаецца наступным чынам:

<�Р> <�ет> праўдзіва , калі OBJ з'яўляецца асобнікам Int32 і роўная значэнню гэтага асобніка; у адваротным выпадку, хлусня .

Гэта таксама тлумачыць, чаму obi.Equals (OBF)) вяртае мана: OBF не з'яўляецца асобнікам Int32.

3
дададзена

Вы бокс ИНТ і паплавок на аб'ект, што азначае, што яны параўноўваюцца як спасылкі. Бо яны не спасылкі на той жа аб'ект, яны не роўныя.

See http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx

1
дададзена

Калі вы абвясцілі два аб'екта яны спасылаецца на іншую вочка памяці:

object obf = f;        //this simplified as new float(f)
object obi = i;        //this simplified as new int(i)

але паспрабаваць наступнае, няхай адзін аб'ект для спасылкі на іншы:

obf = obi;
Console.WriteLine(obf.Equals(obi));

MSDN, Object.Equals Method

<�Р> Рэалізацыя па змаўчанні Равных падтрымлівае роўнасць спасылак для   спасылачныя тыпы і пабітавае роўнасць для тыпаў значэнняў. спасылка   роўнасць азначае, што спасылкі на аб'екты, якія супастаўляюцца ставяцца да   той жа аб'ект. Пабітавае роўнасць азначае, што аб'екты, якія маюць у параўнанні   тое ж самае двайковае ўяўленне.
1
дададзена

Каб лепш зразумець, што адбываецца, калі вы баксаваць тыпы значэнняў, Shivprasad апісвае гэта даволі коратка тут:

бокса і распакаванне

Паколькі вы бокс тыпы значэнняў для аб'ектаў, то зараз выконвае роўнасць спасылак. Бо яны ў цяперашні час пражываюць у розных месцах памяці ў вашым прыкладзе, будзе вяртаць хлусня.

1
дададзена

Паколькі Роўна параўноўвае адрас спасылкі на аб'ект і два ліку захоўваюцца ў розных месцах. калі параўнаць два тыпу значэння роўна паводзіць сябе правільна, так як ён быў перавызначаны для паплаўка, INT, радкі і іншых тыпаў.

0
дададзена

Паколькі яны ставяцца да розных Memeory клетак. 2 = аб'екты толькі тады, калі яны з'яўляюцца тым жа аб'ектам. У поплавковой і ИНТ частцы вы атрымаеце сапраўднае, калі вы выпрабоўваеце 2 зменныя, так як падчас выканання правярае іх значэнне. гэта ўсе!

0
дададзена

Калі вы прыводзіце значэнне тыпу аб'екта, ён на самай справе атрымаць пакласці ў кучу і == параўноўвае спасылкі на той момант, які будзе ілжывым. (Спрошчаны)

0
дададзена