Залепа №8. Крах технологии от обычного int'а.
Автор будет очень признателен, если Вы кликнете по одной из белых ссылок выше.
Вам это ничего не стоит, а автору сайта будет приятно ;)
Все-таки вредно не спать по ночам! Лежал вот, думал. Пытался вникнуть в суть технологии, подстроиться как-то, понять то, что все еще понять не могу, приспособиться и начать (наконец!) получать удовольствие от ее использования. Ведь тысячи программистов пишут под .NET программы и вовсе не страдают от этого, не ощущают никаких неудобств. Вокруг только и слышно: "За .NET будущее", "Самая удобная система", "Передовое решение". Наверное все же я слишком тупой, что не вижу всех этих прелестей.
Вот такие мысли роились у меня в голове и нароили в конце-концов одну идею, которую я и решил тут же опробовать. Даже из постели вылез. На дворе пятый час ночи, а я тут .NET на прочность проверяю! :)
Как я и ожидал, технология мой простейший экзамен с треском провалила! Супер-простое приложение (30 строчек) сработало правильно, но АБСОЛЮТНО НЕЛОГИЧНО. Но, поскольку на дворе глубокая ночь, то описывать происходящее я не буду, просто приведу код программы. Пусть это послужит читателям этаким ребусом, разминкой для мозгов, домашним заданием.
Посмотрите программу, и решите, какой именно она выдаст результат. Потом откомпилируйте ее и сравните реальные ответы с теми, которые вы ожидали. Думаю будет интересно :)
using System;
using System.Collections.Generic;
using System.Text;
namespace GluckTest
{
class MyCls
{
public int x;
public static MyCls operator +(MyCls a, MyCls b)
{
MyCls rez = new MyCls();
rez.x = a.x + b.x;
return rez;
}
}
class Program
{
static void Main(string[] args)
{
MyCls a = new MyCls();
MyCls b = new MyCls();
MyCls c = a; // теперь А и С указывают на один и тот же объект
a.x = 4; b.x = 6;
Console.WriteLine("Before: A={0}, B={1}, C={2}", a.x, b.x, c.x);
a += b;
Console.WriteLine("After: A={0}, B={1}, C={2}", a.x, b.x, c.x);
Console.ReadLine();
}
}
}
Если Вы смогли предсказать верный ответ, то значит Вы очень неслабо разбираетесь в происходящем и дальше Вам читать нет смысла. У меня только один вопрос: считаете ли Вы такое поведение ЛОГИЧНЫМ и УДОБНЫМ для разработчика???
Кстати, в C++ чтобы добиться такого же "эффекта" надо быть оче-е-е-ень глупым программистом! Да и отловится он там моментально, как только вы уничтожите "лишний" объект. А вот в C# причиной является не программист, а именно сама технология и над исправлением этой аномалии придется поломать голову.
Майкрософт уже не один год продвигает .NET (и, конечно же C#) как "более легкую и удобную" среду для разработки приложений, которая "лишена недостатков C++". Приведенный пример, на мой взгляд, очень наглядно показывает, что в C# могут быть неудобства и пострашнее чем в С++.
Немного подумав, можно понять, что программа все же работает правильно и никаких глюков/ошибок тут нет. Но НЕ ДАЙ БОГ вам наступить на такие грабли в вашей реальной работе!
Мой пример, конечно, синтетический. Но давайте мысленно заменим класс MyCls на какой-нить нормальный класс с кучей полей, свойств, интерфейсов, закрытых и открытых методов, а так же "зароем" переопределение операции сложения куда-нибудь в пра-пра-пра-родителя этого класса. А теперь представьте, что Вам необходимо встроить этот класс в свой проект и сцепить его в плотный узел с десятками других классов и тысячами объектов....
Естественно результат работы Вашей программы будет сильно отличаться от ожидаемого и придется потратить массу времени и сил, чтобы разобраться в ситуации и понять в чем дело. И будет очень хорошо, если дружба с отладчиком и вырывание волос на голове прекратится менее чем за неделю. Иначе есть нехилый риск стать пациентом местной психиатрической клиники.
Так в том-то и дело, что при переопределении "+" ДОЛЖЕН создаваться новый объект, а при переопределении "+=" наоборот НЕ ДОЛЖЕН! А в C# он таки создается. В этом и криминал.
Вот тут: http://fit-media.com/post_1198760520.html подробно все описано.
Это не баг технологии, это баг автора. При переопределении оператора возвращается ссылка на новый обьект. Ничего другово ожидать и не стоило.
Faramund (09 марта 2009, 05:29)Уважаемый Faramund.
К сожалению вы абсолютно ничего не поняли из статьи. Если хотите хоть чуть-чуть улучшить свои знания ООП, то рекомендую вам прочесть-таки пояснения на странице http://fit-media.com/post_1198760520.html. А еще лучше найдите хорошую книжку по ООП, она поможет Вам разобраться в вещах, которые Вы не понимаете.
Admin of FIT-Media Blog
Просто нужно понимать, что:
(21 февраля 2008, 09:33)a += x;
в c# это то же самое что:
a = a + x;
и если оператор "+" переопределён и возвращает новый объект... короче, ничего криминального я здесь не вижу.