Comments 49
Тема интересная, но статья попахивает графоманством. Имхо поменьше "шуточек" только пошло бы на пользу. Ничего личного!
Спасибо за ваше мнение! Имхо, шуточек совсем немного (в общей доле всего материала, пожалуй, где-то сотые доли или меньше). Также, имхо, всегда приветствовалась живая подача материала, с юмором, который расслабляет, настраивает на игривый лад (а известно, что в не напряженной, игровой форме лучше всего идет усвоение). Совсем сухо - это справочник читать.
В конечном счете, ~ «вам без шушочек или ехать» :)
Даже если мысль внутри статьи имеет право на жизнь - читать это невозможно.
От стиля статьи прямо как в ламповые 00-е кинуло если не раньше :)
Про плюсы не понял откуда там гранулярный доступ к членам класса. Такого в C++ нет, ни в современном, ни в старом. Есть множество способов указывать друзей (конкретная ф-я, конкретный класс, конкретный метод чужого класса, шаблон...), но любой друг всегда видит всё. Гранулярный доступ к методам в C++ для друзей осуществляется через дополнительный набор ограничивающих интерфейсов поверх данного класса, одна из известных реализаций это идиома Attorney-Client https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Friendship_and_the_Attorney-Client.
удалено, сорри, промахнулся
В C++ можно определять friend-ы только для конкретных функций/методов (не целиком для классов):
https://www.w3schools.com/cpp/cpp_friend_function.asp
(почему-то в конце ссылки символ  добавляет, удалите его после прохода по ссылки и перейдите заново)
Или что имеете ввиду?
Спасибо! Хоть кто-то оценил стиль. Как раз старался чтобы был ламповым. Но видимо не попал в тренд, видимо сейчас в тренде только жесть, только хардкор :)
А можно выжать воду и написать техническую статью? А то мне понадобились значительные усилия, что бы понять о чем статья, несмотря на то, что я знаком и с с# и с с++.
Суть статьи это создание friend-классов (в терминологии c++), возможность определенного класса иметь доступ к не публичным членам другого класса. Но зачем, если в c# есть модификатор доступа internal? Есть ли кейсы где internal не достаточно?
internal дает доступ всем классам в сборке. Пример же (кейс) c# друзей как раз сквозным образом проходит через всю статью.
Я делаю сборку библиотеки и только мои классы могут лезть в internal, пользователи библиотеки не могут трогать internal.
Это расширяет возможности разработчикам библиотеки, но снижает пользователям библиотеки (что б не сломали). А для friend классов какой кейс?
Если в вашей библиотеке пара классов, то может и не вопрос (и то с оговорками). Только разве в реальных проектах часто так? А по кейсу уже писал — пример, сквозным образом проходит через всю статью.
Как знаете, помимо internal есть разные модификаторы доступа. В статье, можно сказать, предлагается еще один, так сказать, elvis-модификатор. Если не видите его специфику, разницу с internal, то, честно говоря, не знаю, что тут еще добавить, кроме того, что уже подробно описано в статье.
Да хоть миллион классов, насколько часто нужно именно запрещать доступ всем остальным, кроме конкретного класса? Мне кажется это очень специфическая задача и проще (возможно даже и лучше) прокинуть доступ через интерфейс/статику/вложенность.
Хотя строго говоря это попахивает нарушением инкапсуляции. Если изменение извне запретили для всех, значит это может нарушить логику работы класса. Если даем разрешение внешнему коду -- есть смысл тогда просто "распаковать" доступ полностью, и делегировать управление внешнему коду.
По моему опыту не так уж и редко для задач со сложной логикой. Если писать к-л типовой проект, бэкэнд рядового интернет магазина какой-нибудь, то там, да, все более-менее линейно. Другое дело, когда задача со сложной логикой.
Как говорил в статье, следуя ФП дао-пути, всегда так стараюсь выстроить систему классов приложения, чтобы классы в идеальном случаем имели только readonly публичные свойства. Увы, как раз для «нелинейных» задач это не всегда просто удается (а если делать не просто, то обычно уж слишком не просто, непроизводительно, не стоит свеч). Некоторые классы оказываются семантически связанными. Какие-нибудь пары например, при работе одного класса-обработчика необходимо скорректировать некоторое свойство в другом. Но в проекте еще очень много классов, которые видят и читают это свойство, этот класс. Поэтому только ради одного кейса открывать его для всех (public { get; set; }) совсем не хочется.
Особенно в больших, командных проектах иногда видел, что чуть ли не все свойства (надо - не надо) имеют публичные get-set. Вот смотришь на миллион таких классов (особенно на чужие, да и на свои сколько-то времени спустя) и чешешь репу — да где же только в этом огромном коде с миллионом классов и миллионом мемберов в них (ладно, не буду вас цитировать — ограничимся хотя бы 1000) не треплют эти свойства? Напоминает пресловутый антипаттерн глобального состояния, только, имхо, хуже, ибо это состояние, размазано по массе классов и попробуй разберись, как оно меняться, если каждый может изменять каждого. А вот если все неизменяемое, то все куда-куда упрощается, намного проще понять логику. И описываемые в статье инструменты позволяют приблизится к этому идеалу.
У меня в проектах практически все классы неизменяемые. Имеются только очень выборочные исключения для некоторых мемберов, которые открыты, но не тысячам других классов, так что они были бы способны их «матросить», а только одному/двум (intellisense же при большом числе классов с их массой мемберов в каждом тут слабо помогает). Смотришь на них и все прозрачно, видишь явную логическую связь — не тысячи возможных нитей-связей, за которые могут все дергать, а одна/две явно прописанные.
прокинуть доступ через интерфейс/статику/вложенность
ну да, про этот как раз в первой половине статьи и писал (см. Me.IFriend)
попахивает нарушением инкапсуляции.
Про инкапсуляцию так бы сказал (собственно писал про это): не нарушает ее, в скорее дополняет еще одним инструментом. Вводит еще один, можно сказать, модификатор доступа, более селективный модификатор (elvis модификатор). И лично мне нравятся такие тонкие инструменты — как инструменты ювелира vs инструменты слесаря, ими уже можно всякую тонкую, так сказать, «часовую механику» налаживать, а не только рубить метал зубилом с молотком. Яйца фаберже vs рессоры от трактора беларусь :)
Еще дополнительные аргументы (там где про объектную модель и связность) привожу в ответе на другой пост:
см. https://habr.com/ru/articles/961264/#comment_29067094
Как же тяжело пробиваться через обилие словоблудия на квадратный пиксель
Хорошо, что не так?
Пробую понять...
Первый с хвостиком абзац — приветствие человека первый раз написавшего здесь статью. Дань вежливости.
Далее немного славословий любимому ФП. Ведь тем более далее будут ссылки на ФП. Совсем-совсем немного! В сентябре вот решил отрефрешить свои знания по Haskell выбрал самую краткую книжку по нему, так там только первые 4 главы (немаленькая часть книги) «словоблудили» в вашей терминологии. И нормально, те кому не нужно (как мне), просматривали по диагонали, кивая головой. Здесь что-ли «пробивались»? Это же как раз легкая часть.
Кстати, после этой статьи была мысль (напрасная? опыт не удался) как раз написать статью по Haskell.
Кроме того, показалось, что читающим будет интересен «линк» между friend и ФП (может и баян, но сам лично не встречал). Такие семантические/ассоциативные связи весьма приветствуются — чем их больше, тем лучше, авторитетно считается, что они активируют креативность у людей. Может и здесь кого-то на что-то, уже свое, по цепочке ассоциаций сподвигло бы.
Кроме того, как писал, это было моей мотивацией. И также известно, что мотивация, мысль-исток из которой развилась к-л теория, важна для лучшего, более глубокого понимания.
Поэтому и есть вводная часть.
Потом идет львиная, центральная часть статьи. Тут уже чисто техническая информация (как вы любите), чуть-чуть скрашенная юмором (простите). Через эти крошки юмора что-ли «пробивались»? Имхо, обычно это как раз самые легкие фрагментики. Ну, если не брать героев анекдотов определенной национальности (все нации уважаю — не я такой, анекдоты такие), до которых долго доходит юмор и они «подвисают».
Есть образы для лучшего восприятия. Вот у вас тоже хороший образ, да еще с юмором: «словоблудия на квадратный пиксель». Так и хорошо выражаетесь. Или только вам можно?
И в конце небольшое заключение. Имхо, интересная (мне точно) мысль о важности законов-ограничений. Есть поверье, что чем больше дается свободы, тем лучше. Здесь же «встречная» мысль. Те же стихи — ограничение на рифму, дает красоту, углубляет смыслы (еще: «тесные врата и узкий путь ведут в жизнь вечную» — вот, еще за цитату заминусуйте). Считал важным это высказать, ибо полагаю важным философским принципом, важным обобщением, взяв за базу которое, кому-то может прийти идея как придумать свои-другие ограничения (так что а, вдруг, вообще придумаете что-то по-круче принципов-ограничений ФП).
Эта часть можно сказать мета-выход за рамки friend-ов. Как отчасти и другие части (каламбурчик) — не только о friend-ах речь (о них и вовсе можно не упоминать, а говорить о новом elvis-модификаторе доступа), но в заголовки же все содержание не выскажешь, а тут приходят и критикуют, мол сбился с темы заголовка (а там, между прочим, есть уточнение: «однако, более того»).
Поэтому и есть заключительная («словоблудная») маленькая часть.
Может тут просто какое-то взаимное недопонимание?
Сократим до поста:
Я захотел сломать объектную модель C# и сделать анализатор, который позволит мне это сделать. Я не знаю, что такое generic-атрибуты и зачем нужно ключевое слово in (но использую его), и сейчас нагорожу свой огород так, что теперь код должен знать своих клиентов, что порождает избыточную связность кода.
Спасибо за code review, правда первый раз от коллеги принимаю его в такой неэтичной форме.
Я не знаю, что такое generic-атрибуты
Почему решили что не знаю? Да еще в категоричной форме высказались ЗА МЕНЯ (да, давно меня так не насиловали! интересно какой у вас опыт работы? а то не верится, что есть коллективы где так принято). Хотя бы спросили — знаю ли?
Так вот: если здесь использовать generic атрибут, то аналайзером не смогут воспользоваться те у кого код написан на C# 10 и ранее.
Не уверен, что стоит отсекать таких пользователей. У меня нет статистики, и просто не знаю насколько массово люди переходят на новые версии. Так что, как говорится, «не уверен — не обгоняй». Если доказательно сообщите мне такую статистику, что, скажем, 99% уже полностью перешли, даже в апгрейдах старых проектов, то можно будет перейти только на этот вариант.
Запись при этом будет чуть лаконичнее, но сути это абсолютно никак не изменит. Чисто декоративное изменение.
Можно сделать как дополнительный вариант задания атрибута к уже существующему для тех кто на C# 11 и выше. Так и проект пока на уровне первого коммита и там, конечно, есть много что развивать о чем сам в статье писал.
Почему сам ранее не подумал над таким возможным дополнительным вариантом?
Знаете, хлопот по проекту и так хватало и хватает, причем уже не чисто декоративного характера.
К тому же стереотип, что generic атрибуты, используются в виде:
class GenAttribute<T> : Attribute {
T _value;
public GenAttribute(T value) => _value = value;
}
[Gen<string>("Hi")] class SomeClass { }т.е. для указания типа аргумента конструктора атрибута, собственно это базовая мотивация их введения в C# 11. Но, в данном случае, в случае использования для целей аналайзера, generic-параметр конструктора будет отсутствовать (в обычной же разработке такой вариант трудно представить).
------------------------------
Я не знаю... зачем нужно ключевое слово in (но использую его)
Опять.
Вероятно в вашем понимании in используется только для передачи больших структур по ссылке в целях оптимизации, чтобы избежать их копирование.
Если так, то почему так узко мыслите?
Использую in как приверженец ФП и ясности. Ибо это сразу вносит ясность, что аргумент метода нельзя переприсвоить. В Kotlin и Rust, как в более современных языках (а значит более склонных к ФП), все параметры по дефолту неизменяемые. Также, к сожалению, в C# нет такого для любых локальных переменных (как это есть в других языках).
------------------------------
Я захотел сломать объектную модель C# и сделать анализатор, который позволит мне это сделать.
Да что же вы опять за меня утверждаете, телепат что ли, чтобы знать что я хочу? Вот прямо «доктор-зло» — хочу сломать объектную модель C#. Единственно верную и непоколебимую модель, что у вас в голове, как истину в последней инстанции?
Устал. Боюсь, что если буду писать про объектную модель, ее понимание, пути развития... то это может вылиться в тот еще холивар.
Так что лишь отмечу, что в плюсах friend-ы вполне себе спокойно существуют. Можно о них спорить. Мое мнение: любой инструмент можно как правильно использовать, так и извращенно до абсурда. В общем, головой пользоваться нужно.
То что предлагается, как писал в статье, можно рассматривать как новый модификатор доступа подобно private, protected... но более селективный. Можно мембер сделать public только для избранных классов/методов... для остальных же будет как private. Это инструмент ювелира, а не слесаря от программирования. И, да, тут тоже нужно головой пользоваться.
Связность?
Вызов метода, изменение свойства в другом классе это тоже связность. Пусть в проекте 1000 классов, каждый с кучей своих мемберов. Но пусть для определенного мембера в определенном классе из всех их лишь некоторым по логике задачи реально требуется доступ. И ради одного кейса открывать доступ всем 1000?
Это так же как вместо private сделать какой-то мембер public, хотя это совершенно не нужно и даже вредно (если его пользование требует сопутствующих согласованных действий для сохранения консистентности данных класса). И надеяться, что никто из джунов-разработчиков других 1000 классов не воспользуются этой открытость (как минимум случайно, но чаще из за дурной креативности, не понимания очень сложной системы в целом, собственно хорошо если ее хоть главный архитектор понимает. данный же модификатор снимает все эти проблемы). И это можно назвать потенциальной связностью и она огромна. А так уменьшаем ее в 1000 раз. А элвис-атрибут, раз в друге этот мембер все равно вызывается и тем самым уже протягивает нить связности, тут ее особо не увеличивает. И, если хотите, то нет проблем определить в аналайзере правило, которое запрещало бы навешивать атрибут если он реально не используется.
Также, оказывается, сколько же других аналайзеров тоже ломают объектную модель, выдавая ошибки компиляции в соответствии со своими доп.правилами к ванильному C#?
Если кто-то не может представить таких ситуаций, когда это может быть полезно, то на мой, сугубо личный взгляд, такой программист, либо имеет мало опыта, либо все время имеет дело с какими-то линейными задачками, типа всю жизнь штампует бэкэнды с типовой архитектурой, не сталкивался с реально сложными, нестандартными задачами. А так сам, если что, много чего не знаю.
------------------------------
Исключительно для того чтобы лучше донести до вас, зеркалю и пишу следующие утверждения от ВАШЕГО имени:
Я не знаю что такое элементарная этика.
Я считаю себя истиной в последней инстанции.
Я не смог понять материал статьи.
Я трахаю животных. (чисто для усиления понимания неэтичности)
...
Но зачеркиваю их, не подписываюсь под ними, ибо не позволяю себе такого.
Даже если я 100% уверен, что кто-то ошибается, то отношусь к нему с уважением, ибо «каждый человек имеет право на ошибку» (из старой восточной мудрости) и я уважаю его права.
Психологи же скажут, что неуважительно, т.е. пытается унизить собеседника, тот, кто тем самым хочет за счет другого повысить свою самооценку, а значит внутренне глубоко ущербный человек (и как правило не отдает себе в этом отчета). Просто общий факт ни на кого конкретно не нацеленный, и если что, сам себя считаю во многих аспектах ущербным, «не ангел» (увы мне, и надо работать над собой).
Извиниться не хотите за неэтичное поведение?
Вы же извините, если был несколько резок, хотя и не переходил грань этики. Реакция определилась тоном вашего поста. Предпочитаю приятную, уважительную беседу (ту самую «роскошь общения» по Экзюпери), когда получив положительные эмоции от общения каждый выходит обогащенным. Даже если один оказался полностью не прав, то другой получает возможность уважительно помочь человеку, а это ценно само по себе, ибо через помощь другим и развивается, растет личность.
P.S. Даже если принять ваши слова, что «ломает объектную модель C#» («нагородя свой огород»), хотя не согласен с таким словом — не ломает, а дополняет. Так и что? Модель ООП (или ФП) «ломает» модель чисто процедурного программирования. И что «ужас-ужас!»?
Каждая новая версия языка «ломает» предыдущую — ошибки компиляции для новых фич. Также как и многие-многие аналайзеры могут выдавать ошибки компиляции согласно своим правилам. Обычно придерживаются принципа обратной совместимости. А бывает, что и не придерживаются как с Python 2 и Python 3. Реально сломали, без кавычек. И что? Правильно ведь сломали — Python 3 лучше. Часто мне хочется чтобы и C# сломали, ибо накопилась «борода» легаси, что тормозит развитие, как накапливаются тормозящие гирлянды ракушек на днище старых кораблей.
Просто подключение данного аналайзера, абсолютно не влияет на ошибки компилятора, как если бы и не подключали. А вот дальше уже сам программист, если сочтет нужным, может управляемо «сломать» ванильный вариант, оставаясь в рамках C# синтаксиса, просто навесив определенные атрибуты. Подключая голову, а не безбашено лепя атрибуты на каждый мембер и класс. По моему опыту, для задач со сложной логикой это где-то один отмеченный мембер на сотню классов.
И вопрос: почему вы выбрали именно слово «ломает» («нагородя огород»)? Чтобы повысить за мой счет свою самооценку? (мол, смотрите все, вы дурак со своей программой и соответственно я умный на вашем фоне? или как?)
Суть в том, что теперь методы можно вызывать лишь из определенных методов.
Не хватает:
1) вызова только из определенных Namespace, из определенных классов\интерфейсов.
2) Вызывать отовсюду, кроме...
3) nuget-пакета с тестами
4) внятного стиля изложения
1) Да namespaces можно добавить для коллекции (также как и поля...). А "из определенных классов\интерфейсов" сделано (про это есть в статье).
2) В принципе можно добавить и инверсию, правда пока плохо представляю, где это может быть полезно.
3) Пакеты с тестами... Помилосердствуйте, это только первая версия. И так замаялся все это оформлять - реально труд великий с этой статьей, подготовкой материалов, публикаций nuget пакетов, расширений,... да хотя бы картинку оформить... И, как оказалось, заминусоваили. Склоняюсь к тому, что больше нет смысла писать статьи (хотя идей много), первая и последняя - людям не нужно.
4) Понять и простить.
На мой вкус вот эти плюсовые friends - это какой-то рудимент, который только запутывает логику приложения и делает зависимости менее прозрачными. Как хорошо, что его не стали тащить в C# разработчики языка.
Текст имеет все признаки гпт (да и код), читать невозможно.
Можно конкретно написать, какие признаки GPT? Так же вместо того, чтобы приписывать невесть что, можно ведь просто спросить (именно это будет этично). И если бы меня спросили ответил: Текст писал ИСКЛЮЧИТЕЛЬНО сам. Разве не видно, что он имеет индивидуальные черты — мышление у меня поливалентное, не одномерное, со множеством ассоциаций, думал люди оценят, улыбнутся. Разве так пишет GPT? И опять, считаю что без конкретики — это как, вот вам ассоциация, если понравится: вброс сферического г..(галоши?) в вакуум (а раз вентилятор в вакууме не функционален, то точно галоши).
Так же как и код писал «вот этими вот руками». Заглядывал за некоторыми деталями в доки и в google конечно (а у него, конечно, gemini в первой строчке), ибо все детали того же Roslyn помнить невозможно (разве только на нем узко специализироваться 10 лет подряд). Никаких же промптов типа "напиши мне целиком такой-то ... проект",... готово, выкладываю — и в помине не было (хотя даже не знаю, хорошо это или плохо, скорее плохо).
И какой код? Примеры в статье? (вот их точно абсолютно никуда не глядя писал). В репозитории? Если там, то что конкретно там не так?
Почему люди не пишут о самом материале статьи, вместо этого практически переходя на личности?
Посмотрел вашу ссылку.
Какой-то там куций функционал. Только для класса, только для internal, а может и только для static - непонятно из их единственного примера и описания:
https://github.com/piotrstenke/Durian?tab=readme-ov-file#friendclass
В то время как для классов — это как раз наименее интересный случай. Там имеем похожие недостатки что и в плюсах, о которых писал («эксгибиционизм» членов класса).
И главное — не музыкально. При написании кода Элвиса не напеть.
P.S. А у вас статьи, кстати, интересные.
Я честно пытался...
Эх, может хоть кто скажет, где именно трудности?
Вот прям уже «Фигаро тут, Фигаро там» (или как сапер — «одна нога здесь, другая там»), разрываюсь, пытаюсь всем угодить, на каждый коммент максимально развернуто ответить, пытаюсь понять по очень скупым туманным фразам, что человек имеет ввиду. Вас, дорогие коллеги, похоже мне (конечно только мне) понять еще труднее.
Где? В вводной части? Обычно такие, лирико-хвилософские вводные части в книжках быстро «проглатываются».
Может в той, где сравнивается C# и C++? Ну она, как писал, вбоквел, только для тех Матроскиных, кто хорошо знает оба языка, ее можно без всякого ущерба пропустить.
Хотя, пожалуй, для понимания некоторых замечаний в других частях, все же надо представлять что такое friend-ы в плюсах. Может надо было дать вначале краткую справку? Если в этом дело, только скажите — добавлю.
В основной, технической части?
Не верится, что фрагменты с юмором мешают, их можно тоже пропускать без ущерба.
Сам пример, что сквозным образом проходит через всю статью? Разве он не элементарен?
Думаю, скорее всего что-то в самом техническом контенте.
Что именно? Какая фраза/абзац вызывают затруднения, требуют дополнительного пояснения? Можно несколько примеров?
Когда оформлял статью, думал какой уровень сложность ей поставить, колебался между "Простой" и "Средний". Может тут ошибся и надо было ставить "Сложный"?
ИМХО. Чрезвычайно приторная, перенасыщенная над-юмором статья, переизбыток жеманства, пословиц, поговорок, отсылок и аналогий на предложение. Много воды, ребёнка надо ещё поискать.
И пусть, с одной стороны, у меня есть 100 рублей (св-во Rubles).
А с другой, ведь «не имей сто рублей, а имей сто друзей», а также у друзей ведь все должно быть «на лапопам», не так ли? Так что готов разделить с ним рубли. Хочу дать другу «ключи от квартиры где деньги лежат» — приходи дорогой, бери половину рублей из тумбочки.
Можно брать любой кусок статьи, хоть вот этот. Если к каждому слову торопиться рифмовать подвернувшуюся пословицу, да ещё и присказку в придачу, то лучше не становится. Отнюдь. Какие ключи? Какие рубли? Какие квартиры? Какие тумбочки? Аааа ))))
Когда оформлял статью, думал какой уровень сложность ей поставить, колебался между "Простой" и "Средний". Может тут ошибся и надо было ставить "Сложный"?
Тема простая. Но лёгким чтивом это не назовёшь. Моментально теряешь смысл в потоке избыточной информации. Хорошо, что есть нейронки и можно получить пересказ :)
Это поясняемая цитатами и пословицами — доказательная логика: почему число 100, а не любое другое как могли бы недоумевать, и почему надо делится с другом, и почему именно «на лапопам».
Чтобы не было вопросов что тут за цифры и действия такие взятые с потолка или с бодуна. Так сказать описание предметной области, которая будет моделироваться программой. Ну и постарался сделать это не скучно. А без цитат, ссылок-отсылок в серьезных изданиях так вообще не примут статью :)
По идее такие описания должны восприниматься влет, легко и приятно, как хорошо знакомые и ярко-выпуклые образы, легкими мазками рисуя в воображении читателя живую «картину маслом» (эх, вот опять не удержался от цитаты). Если же спрашиваете: какие ключи, рубли, квартиры, тумбочки. То значит можно сделать вывод, что не находитесь в классическом русском контексте пословиц, мемов, литературной и кино-классики. Вот с этим ожиданием от читателя возможно и промахнулся. Переоценил народ в этом плане.
Хотя это больше про небольшие вводную часть и заключение (как уже говорил), в которых традиционно вполне допускаются лирические ноты. Основная же часть должным образом (как многие требуют) скучная. Ну а редкие вкрапления юмора... так в чем проблема просто пропустить их, если этот юмор не понятен? (ну или у меня он такой не смешной или слишком требовательный к читателю, эх, а ведь старался веселить, т.е. вызывать положительные эмоции).
Честно говоря даже верится что вот это было непреодолимое препятствие, имхо, даже одних примеров кода, которыми постарался обильно снабдить статью, достаточно. Больше похоже на то, что некоторые просто не поняли (поленились) материал статьи, об этом говорят и некоторые из их постов (развернуто отвечал на их все).
Вам дали пересоленную еду. Вы говорите: невозможно есть, она очень-очень солёная, соль даже скрипит на зубах. Но вам отвечают: вы просто глупый, ленивый, поверхностный, не разбираетесь в кулинарии, и вообще вот вам две, даже три часовых лекций на тему, почему вы должны поверить, что это шедевр.
Научитесь, наконец, принимать критику, как взрослый человек. Ваши кирпичи текста в комментариях не добавляют ясности, а только ещё больше усугубляют. Вы не обязаны с каждым соглашаться, но обвинять окружающих в лени, тупости, посредственности только потому что не оценили ваших художеств — хамство, не иначе.
Спасибо за ваше мнение, оно очень ценно для меня!
И после этого вы говорите, что не воспринимаю критику? :)
Уважаемый, очень взрослый человек, стесняюсь спросить: а на критику можно отвечать, просить аргументировать? Или только в духе «ему ссут в глаза — а он божья росса». Ибо как можете заметить она тут очень лаконична, без аргументации, порой просто фразой-эмоцией, и если бы она была применена к вам, то возможно (возможно, не настаиваю конечно), то вы бы ее, наверное (наверное) как раз и назвали детским садом.
Как же мощно вы меня припечатали, просто намотали на гусеницы: «вам отвечают: вы просто глупый, ленивый, поверхностный, не разбираетесь в кулинарии».
Позвольте, ну не совсем все же верно (хотя иногда и бывает что туплю) и это не мое мнение, «у меня и справка есть» (и совсем не об окончании «кулинарного техникума» и совсем даже не на двойки, а с точность наоборот).
«Ленивый»? (хм, труд проделал огромный — реально, + тут, стараюсь, каждому очень-очень развернуто отвечаю, задаю вопросы...). Признали щедевром? Где на такое надеялся? Пожалуйста, прошу, не надо за меня выдумывать, ведь это справедливо считается очень не этичным. В таких случаях просто спросите меня, если хотите знать что реально думаю (а не что вы думаете, что я думаю, что я думаю).
Да и отвечают не все как вы, есть тут совершенно другие мнения.
Замете, остаюсь с вам в рамках вежливого общения, несмотря на откровенное хамство.
А теперь можете ставить свой очередной минус (ну если захотите, конечно, ведь не вежливо указывать другим что им делать, так что, конечно, не настаиваю).
Уважаемый, мне тяжело было читать вашу статью. Мне очень не понравился ваш стиль. Читать было неприятно. И еще более неприятно читать ваши комментарии, ваши нелепые ужимки, детские оправдания, и глупые попытки переложить с больной головы на здоровую. Я первым словом в ответ вставил "ИМХО". Понимаете, что это значит? И я уже окончательно убедился, что у вас какие-то серьёзные проблемы с самооценкой. Особенно потоки приторной лести и лизоблюдства в ответ на редкую похвалу. Испанский стыд. Успокойтесь пожалуйста.
полная цитата вашего поста на который ответил:
Вам дали пересоленную еду. Вы говорите: невозможно есть, она очень-очень солёная, соль даже скрипит на зубах. Но вам отвечают: вы просто глупый, ленивый, поверхностный, не разбираетесь в кулинарии, и вообще вот вам две, даже три часовых лекций на тему, почему вы должны поверить, что это шедевр.
Научитесь, наконец, принимать критику, как взрослый человек. Ваши кирпичи текста в комментариях не добавляют ясности, а только ещё больше усугубляют. Вы не обязаны с каждым соглашаться, но обвинять окружающих в лени, тупости, посредственности только потому что не оценили ваших художеств — хамство, не иначе.
Где "ИМХО" то? Или не только у меня проблемы?
И вам что завидно, что на вежливый положительный ответ — вежливо положительно ответил? (если так, то, пожалуйста, не надо, читал, что согласно статистики, зависть — основная причина депрессий в США, поберегите себя).
Впрочем и вам и всем вежливо отвечаю (так что, еще раз, пожалуйста, не приписываете мне своих мыслей). Более того, даже вам вот ниже постом немного отлизаблюдил (в вашей терминологии).
Также благодарю вас, что отслеживаете и собираете библиографию моих постов (вот еще раз вам отлизаблюдил). Не хотите стать моим летописцем?
Коллега, а вы не находите, что вы мне тут столько всего наговорили, столько своих непрошенных оценок навешали, что тут можно долго разбирать всякие ваши issues, давая встречные оценки (может даже «букетик» issues? как это принято мягко называть в английском, ведь у них всегда «no problem», это только у меня по вашим словам серъзные problems). Но нет, так никак не могу, ведь как и все воспитанные люди, понимаю, что без запроса от собеседника самому давать ему оценку крайне не этично. В свою очередь, извините, если где-то невольно что-то проскочило.
И вот что мне странно: у меня есть сейчас время (ведь ~ «ленивые часов не наблюдают»), и я с удовольствием общаюсь с вами (получаю «роскошь человеческого общения»). Вдруг меня (глупого конечно), умные и взрослые дяди научат не только плохому, но и чему-то хорошему (и да, есть уже результаты/выводы, спасибо всем!). А вам вот все не нравится, но вы упорно продолжаете общаться (на кактусах тренировались?). Все-таки какие мы все разные и как же это интересно!
Очередной кирпич текста с оправданиями и наездами ) сказка о потерявшемся ИМХО )
Ну, да, извините, что уделяю вам свое время, внимательно читаю ваши посты и стараюсь максимально полно ответить вам. Пожалуйста, не будьте к себе строги, уверяю, «ведь вы этого достойны!». Так что какие наезды? Извинения и благодарности. Хотите знать что такое наезды? Тут далеко ходить не надо — есть, есть тут характерные посты, можете перечитать на досуге, если забыли.
«ИМХО», конечно было в одном вашем хорошем посте, на который, имхо, хорошо ответил.
Только отвечали то вы мне, а потом я вам на содержание другого поста, гораздо ниже. Потеряли контекст? Тот ваш пост, который уже, как бы это помягче сказать чтобы вас не обидеть... Ай, не буду говорить, не хочу вас обижать, дорогой коллега.
А что с оправданиями не так? Не имею право отвечать? А кто тогда защит меня бедного детсадовца от взрослых и таких невообразимо умных дядей?
Даже вот очень известная фраза гласит: «...Вы имеете право на адвоката. Если вы не можете позволить себе адвоката, он будет назначен вам бесплатно».
Тогда требую бесплатного адвоката! Пусть он меня оправдывает, а я буду «хранить молчание».
Вчера, понимаешь ли, утро было как обычно — солнце светит, холодильник пуст, носки разные, но сердце просит приключений. Думаю: «Надо выйти в люди. Пусть хотя бы они видят, что я ещё жив». Вышел из дома, ветер дует, голуби обсуждают политику, а я иду, как человек без цели, но с надеждой.
И тут — бах! — кофейня. Новая, блестящая, как freshly installed Windows, только без синих экранов. Вывеска сияет: «Кофе & Смысл жизни». Ну, думаю, если не тут, то где?
Захожу. Запах такой, будто ангелы жарят бобы на облаках. За стойкой — бариста, лицо у него как у человека, который знает все тайны мироздания, но делится только за доплату 50 рублей. Спрашивает:
— Что будете?
А я растерялся. Мозг крутит варианты, как старый принтер. И вдруг из меня вырывается:
— Латте…
Почему латте? Не знаю. Может, потому что звучит, как имя итальянского философа.
Бариста кивает. Машина шипит, парит, свистит — будто паровоз на пути в Город Удовольствия. Я стою, нюхаю воздух, и вспоминаю детство, деревню, корову по кличке Зорька и как бабушка говорила: «Пей молоко — вырастешь большим, а кофе — это для тех, кто уже вырос, но жалеет об этом».
Через минуту он ставит передо мной чашку — белоснежная, с рисунком в виде сердечка, или, может, лёгкого разочарования — я не уверен. Пенку можно было бы использовать как строительный материал — плотная, как аргументы тёщи.
Делаю глоток.
И всё.
Мир перевернулся.
Я понял, что все философы ошибались — смысл не в бытии, а в балансе между молоком и кофе. Это как если бы Будда и Эспрессо устроили совместный стартап.
Вкус — божественный! Мягкий, как комплимент от налоговой. Нежный, как кошка, которая впервые признала твоё существование. И бодрит так, что даже мысли начинают бегать по кругу, устраивая утреннюю зарядку.
Сижу, пью, размышляю: вот ведь жизнь — идёшь просто прогуляться, а оказываешься в кружке с молочной пенкой. Народная мудрость не зря говорит: «Без кофе и печаль не та, и радость подозрительная».
Вокруг люди с ноутбуками, каждый делает вид, что пишет роман. Один парень так напряжённо смотрит в экран, будто там прячется его зарплата. Девушка рядом фотографирует свой макиато под углом 45°, чтобы лайки сами ставились. А я — я просто открываю новые горизонты вкуса и смысла.
Выходил я из кофейни уже другим человеком. Воздух стал чище, улицы — философичнее, а в голове вертелась новая пословица:
«Кто латте не пил, тот жизни не видел. Кто пил — тот теперь знает слишком много».
И вот и думай теперь, зачем я вообще туда пошёл. Может, судьба привела, может — маркетинг. Но если резюмировать (для тех, кто не осилил 18 абзацев):
Вчера я пошёл в кофейню, решил впервые попробовать латте — и оказалось, что это чертовски вкусно.
Табличка «сарказм» нужна? Есть определённые места, где можно поражать воображение людей своей беллетристикой. Дзен, например.
Некоторые образы понравились, реально хороши (не ai случайно? просто похоже). Единственное, уж очень, очень, имхо, гипертрофировали в попытке сарказма.
Чашка кофе с ложной сахара и чашка сахара с ложной кофе - чувствует разницу?
Но не настаиваю, не осуждаю «вы художник — вы так видите».
У меня свое мнение, у вас свое. Или считаете это ненормальным?
Я считаю, что в первую очередь на данном ресурсе ценностью является техническая часть, а не художественная. Писать лаконично и по делу — искусство. Здесь я прихожу образовываться, получать знания, учиться на чужом опыте, делиться мнением, участвовать в обсуждении технических аспектов и деталей. Обилие шутеечек и не в меру художественный обвес только всё портят.
Так давайте и обсуждать техническую часть, а не художественную. Рассчитывал, что именно-именно так и будет. Только и только «за» и руками и ногами.
Вместо этого в основном переход на личности (причем «заметьте, не я это предложил» — такую тему, или мне стоит быть польщенным к такому вниманию к моей личности?).
Да, есть у меня свои индивидуальные особенности. И народ за них зацепился (а мне вот не нравиться как мой сосед одевается, но тем не менее хорошо общаюсь с ним, никогда не поднимая тему его одежды). Их можно либо попытаться понять (и даже вдруг тут открыть для себя что-то новое, моим друзьям/знакомым — нравится), либо абстрагироваться от них. Тем более в технической части статьи этого немного. Ну либо, на самый худой конец, вот так как сейчас... хорошее тут слово было в постах, а вот, нашлось — «наезжать» (можно позаимствую?). Тоже вариант и ваше право.
Т.е. что же это получается? По факту многие люди здесь показали, что им гораздо важнее художественная, а не техническая часть? Одежка, а не внутренность?
Знал бы что будет такая неожиданная реакция — конечно по другому бы написал, для вас дорогие коллеги, сломал бы себя (пусть и поется в песне «Но не смотри, не смотри ты по сторонам, Оставайся такой, как есть, Оставайся сама собой...»).
Это первая (и похоже последняя) моя статья, о чем писал в самом начале и просил «Пожалуйста, позаботьтесь обо мне».
Что же, так вот она какая забота («вот он какой северный олень»), Ваше право.
P.S. И может быть если бы вы чуть лучше разбирались в людях (простите, если ошибаюсь) то знали бы что часто люди шутят не от хорошей жизни. Жизнь боль и не только своя, но и близких. А юмор он помогает держаться. Если у вас все прекрасно, то реально рад за вас (всегда молюсь чтобы Господь и дальше хранил счастливого человека которого вижу).
Классная статья! Честно, не понимаю, что людям не нравится, я хоть и никогда не работал с C#(плюсы only), но все отлично понял, подача материала годная, читать приятно. Респект автору в общем)
Спасибо Огромное! Ваш комментарий особенно ценен на фоне превалирующего непонимания.
Почитав иные комменты, считаю, что люди просто не поняли материал статьи.
А некоторые, похоже, даже не потрудились дочитать (но осуждают). Особенно первые 2 мгновенных минуса, сразу, в ту же минуту, после публикации. Возможно это были северо-корейцы, которые прочитали лишь первый абзац со ссылкой на цикл о Южной Кореи (но ведь тоже не потрудились прочитать цикл, ибо там совсем не воспеваются порядки южан).
Написал, имхо, полезный инструмент, выложил в открытый доступ, берите пользуйтесь на здоровье, если кому понадобится.
Статью с любовью запилил, стараясь ее сделать не скучной, чтобы люди не засыпали на бубнеже о технических деталях, разбавил шутками юмора.
Хотя это больше про небольшие вводную часть и заключение, в которых традиционно вполне допускаются лирические ноты. Основная же часть, имхо, должным образом (как многие требуют) скучная.
Даже не ожидал, что это будет такая огромная работа (причем все «безвозмездно, то есть даром» от чистого сердца).
И, думаю, конечно, тут каждому будет по человечески обидно.
Сижу-гадаю: «что же вам, собаки, еще надо-то?!»
Ладно, извиняюсь (пред теми кто отнес на свой счет, не понял юмора, цитаты) — собаки зачеркиваю, это я сгоряча, на эмоциях. Хотя «собака — друг человека», так что вполне в рамках тематики статьи :)
Некоторые вообще за рамки элементарной этики выходят (поплачусь в жилетку):
https://habr.com/ru/articles/961264/comments/#comment_29059274
Настолько в когнитивном диссонансе от «ожидание и реальность», что, думаю, уже никогда здесь больше не решусь написать что-либо еще (хотя идей достаточно).
Так что, еще раз, моя вам искренняя благодарность за понимание, умный, образованный, с хорошим чувством юмора человек.
Сложное решение несуществующей проблемы.
В данном простом примере откровенно говоря было бы проще сделать абстрактный класс с protected полем и унаследовать оба от него. А глобально мы создаём не очевидные зависимости и раздуваем код сложно читаемыми (по крайней мере для стороннего программиста) атрибутами и псевдонимами. Решение, имхо, вызывает больше проблем, чем проблема internal поле, которое оно решает. Keep It Simple Stupid. Может быть грубовато, но на западе такое зовут overengineered garbage code.
Генераторы кода вещь крутая, несомненно, но для замены рефлексии, а подобным выкрутасам я ещё должен увидеть применение. Возможно в будущем кто-то докажет мою неправоту. А причина почему в C# нет friend не функциональность, а скорее безопасность, это нарушает контракт private и ломает гарантии, в том числе для JiT
Как это принято, чтобы продемонстрировать концепт, для ясности приводится самый простой пример. И, конечно же, для таких примеров могут быть альтернативные решения, иногда более сложные решения иногда менее (да всегда есть альтернативные решения, более того, даже тот же C++ можно было не изобретать, ведь все задачи можно и на C решать — вопрос простоты/удобства). В реально жизни же такие демо-примеры — редкие исключения. И зачем, кстати, в стандарте C++ есть friend-ы? Вот, Stupid люди, ввели для несуществующих проблем.
было бы проще сделать абстрактный класс с protected полем и унаследовать оба от него.
Во-первых: а что если какой-либо или сразу оба класса уже имели базовые классы, так что для нового базового абстрактного класса уже не было бы места? (как знаем, в C# нет множественного наследования в отличии от плюсов)
И как уже писал в других комментах, этот инструмент может быть особенно полезен для программ со сложной логикой (там все места обычно заняты), а не «линейных», типа где почти лишь DTO-шки, ORM-отмаппенные классы из дата-сетов + шаблонные контроллеры созданные IDE для вас. Боюсь, что недоумение «зачем это нужно?» от некоторых здесь, и связано с тем, что люди привыкли заниматься такими шаблонными задачами (и это реальность почти всех разработчиков, сам большинство таких задач и решаю, но скоро AI вытеснит программистов из шаблонных задач). Это инструмент для сложных задач, для «ювелиров» настраивающих сложный часовой механизм vs «слесарей» занимающихся рубкой метала где инструменты это молоток и зубило.
Во-вторых: пусть не «во-первых» (т.е. место под базовые классы все же есть), и если правильно вас понял, предлагаете:
abstract class Base { protected decimal Rubles; }
class Me : Base { }
class MyFriend : Base {
public void AcceptMoney(Me me) {
decimal half = me.Rubles / 2; // error
me.Rubles = half; // error
Rubles += half;
}
}Увы, компилятор не согласен (2 ошибки компиляции).
Если же поле определить как:
internal protected decimal Rubles;То оно уже будет доступно и всем другим классам в проекте, а не только наследникам Base.
Как вариант решения этой задачи без атрибутов (решение более сложное + с недостатками оговоренными в статье) — см. пример с Me.IFriend интерфейсом в статье.
создаём не очевидные зависимости и раздуваем код сложно читаемыми (по крайней мере для стороннего программиста) атрибутами и псевдонимами.
Вы действительно считаете, что добавить ВСЕГО ОДНУ СТРОЧКУ с атрибутом и означает все что вы тут написали? Одна строчка:
[OnlyYou(typeof(MyFriend), nameof(MyFriend.AcceptMoney))]
public decimal TakeMyHalfMoney()В еще более лаконичном варианте, так:
[OnlyYou<MyFriend>(nameof(MyFriend.AcceptMoney))]А на счет зависимостей (их иллюзорности) можете почитать мой ответ в другом комменте — прокрутить до места, где отвечаю коллеге про объектную модель (и связность):
https://habr.com/ru/articles/961264/comments/#comment_29067094
И что, разве через определения базовых классов, наследования для каждого, создания всей этой иерархии зависимостей... разве код уже не раздуваем, не делаем сложно читаемым (vs ясного и лаконичного OnlyYou атрибута одной строкой)?
А причина почему в C# нет friend не функциональность, а скорее безопасность, это нарушает контракт private и ломает гарантии, в том числе для JiT
Если внимательно почитаете статью, то найдете, что как раз это критикую в C++ friend-ах. Хотя friend-ы вполне себе входят в стандарт C++.
Как уже отмечал, имхо, при использовании любого инструмента нужно пользоваться головой, ибо всегда, даже самый хороший инструмент можно извратить, довести до абсурда в его применении. Это касается и инструментария в статье. По моему опыту, даже в сложных задачах, применение elvis-модификатора в среднем требуется к 1 методу на 100 классов, а вовсе не безбашено лепить на каждый метод, каждого класса.
Важно: Как писал и в статье и во многих комментах, предложенный подход уже не совсем аналог плюсовых friend-ов. Другой инструмент, избавленный от важных недостатках плюсовых friend-ов. Можно сказать, это вообще не friend-ы. Они были лишь одной из мыслей-истоков, аналогией от которой оттолкнулся.
Правильнее говорить о новом, более селективном модификаторе доступа (elvis-модификаторе). Модификатор не открывает приватные члены (не нарушает private контракт), а делает селективным доступ к публичным.
Например, вот где (помимо статьи) более подробно говорю:
https://habr.com/ru/articles/961264/comments/#comment_29068288
А private контракт ломает разве что рефлексия.
Аналайзеры же (тем более без фиксов как здесь) в принципе ничего не ломают, а лишь выдают ошибки/предупреждения при компиляции. Более того, если программист сам явно не добавит elvis-модификатор, то аналайзер никак себя и не проявит, как если бы его и не добавляли в проект.
Чтобы не путали с friend-ми даже возникло желание переименовать проект в ElvisAnalyzer (+ маркетинг хороший, хотя все бесплатно, все для вас дорогие, хоть бы кто спасибо сказал, кроме одного, только ругают и минусуют).
---------------------------
Спасибо вам большое, что хоть задали технические вопросы, а то, к сожалению, тут скорее заняты художественным аспектом (некоторыми аспектами «одежки» статьи, а не сутью) и моей личностью, даже не приводя конкретные аргументы.
Впрочем, и вы без наездов на мою Stupid личность не обошлись :) (хотя, реально, бывает туплю) Но уже и такому рад — «на безрыбье и рак рыба», коль без наездов никак (если что, просто поговорка, а не обзываю вас «раком», уважаемый коллега).
Добавил в аналайзер короткий (в 100ms) консольный бип, фактически трещетку. И убедился, что аналайзер действует очень экономно — анализирует только тот файл на который смотрим. И даже похоже учитывает прокрутку, т.е. только тот кусок что видим. При открытии файла выдает очень короткую дробь, а при первой (только первой) прокрутке можно услышать одиночные щелчки. При редактировании — та же очень короткая дробь, несмотря на > 1000 зависимых файлов.
Метод профилирования и диагностики, достойный drive2.ru))
Заводим друзей в C# (аки C++ friend, однако, более того)