Почему C # не предоставляет ключевое слово 'friend' стиля C ++? [закрыто]

++ класс Ключевое слово C позволяет class Bобозначить , Class Bкак его частный. Это позволяет protectedполучить доступ к class A/ friendчленам friend.

Я никогда не читал ничего о том, почему это было исключено из C # (и VB.NET). Большинство ответов на этот более ранний вопрос StackOverflow, похоже, говорят, что это полезная часть C ++, и есть веские причины для ее использования. По моему опыту, я должен согласиться.

Мне кажется, еще один вопрос - действительно спросить, как сделать что-то подобное internalв приложении C #. Хотя ответы обычно вращаются вокруг вложенных классов, это не кажется столь же изящным, как использование internalключевого слова.

В оригинальной книге «Образцы моделей» она регулярно используется на всех примерах.

Итак, вкратце, почему friendотсутствует C #, и каков способ «лучшей практики» (или путей) имитации этого языка на C #?

(К слову, [InternalsVisibleTo]ключевое слово - это не одно и то же, оно позволяет всем классам всей сборки получать доступ к friendэлементам, а также internalпозволяет предоставить определенный класс для полного доступа к одному другому классу)

c#,c++,design-patterns,oop,friend,

191

Ответов: 23


61 принят

Наличие друзей в программировании более или менее считается «грязным» и легко злоупотреблять. Это нарушает отношения между классами и подрывает некоторые фундаментальные атрибуты языка OO.

Это, как говорится, хорошая функция, и я использовал ее много раз на C ++; и хотел бы использовать его в C # тоже. Но я держал пари из-за «чистого» OOness C # (по сравнению с псевдо-OOness C ++). MS решила, что, поскольку Java не имеет ключевого слова для друга, C # тоже не должен (просто шутите;))

На серьезной ноте: внутренняя не так хороша, как друг, но она выполняет свою работу. Помните, что редко вы будете распространять свой код сторонним разработчикам не через DLL; так что, пока вы и ваша команда узнаете о классах друзей и их использовании, вы должны быть в порядке.

EDIT Позвольте мне пояснить, как ключевое слово friend подрывает ООП.

Частные и защищенные переменные и методы, возможно, являются одной из наиболее важных составляющих ООП. Идея о том, что объекты могут хранить данные или логику, которые только они могут использовать, позволяет вам написать свою реализацию функциональных возможностей независимо от вашей среды - и что ваша среда не может изменять информацию о состоянии, которую она не подходит для обработки. Используя друга, вы комбинируете реализацию двух классов вместе, что намного хуже, если вы просто связали их интерфейс.


93

На боковой ноте. Использование друга не связано с нарушением инкапсуляции, а, наоборот, связано с его применением. Подобно аксессурам + мутаторам, перегрузкам операторов, публичному наследованию, понижению и т. Д. , Это часто неправильно используется, но это не означает, что ключевое слово не имеет или, что еще хуже, плохой цели.

См Konrad Rudolph «s сообщение в другом потоке, или , если вы предпочитаете видеть соответствующую запись в FAQ C ++.


45

Для информации в .NET есть еще одно связанное, но не совсем то же самое internal, что позволяет сборке обозначать другую сборку (например, сборку единичных тестов), которая (эффективно) имеет «внутренний» доступ к типам / членам в оригинальная сборка.


12 ов

Вы должны иметь возможность выполнять те же самые вещи, которые «друг» используется для C ++, используя интерфейсы на C #. Это требует, чтобы вы явно определяли, какие члены передаются между двумя классами, что является дополнительной работой, но может также облегчить понимание кода.

Если у кого-то есть пример разумного использования «друга», который нельзя моделировать с помощью интерфейсов, пожалуйста, поделитесь им! Я хотел бы лучше понять различия между C ++ и C #.


12 ов

С friendдизайнером C ++ имеет точный контроль над которыми частные * члены подвергаются воздействию. Но он вынужден разоблачить каждого из частных членов.

С friendдизайнером C # есть точный контроль над набором частных членов, которые он раскрывает. Очевидно, он может выставить только одного частного участника. Но он будет доступен для всех классов сборки.

Как правило, дизайнер хочет выставить только несколько частных методов для выбора нескольких других классов. Например, в шаблоне фабрики классов может потребоваться, чтобы класс C1 был создан только классом фабрики CF1. Поэтому класс C1 может иметь защищенный конструктор и класс CF1 класса друзей.

Как вы можете видеть, у нас есть 2 измерения, по которым может быть нарушено инкапсуляция. friendнарушает его по одному измерению, internalделает это по другому. Какой из них хуже в концепции инкапсуляции? Сложно сказать. Но было бы неплохо иметь и то, friendи другое internal. Кроме того, хорошим дополнением к этим двум будет ключевое слово 3-го типа, которое будет использоваться по принципу «один за другим» (например internal) и задает целевой класс (например friend).

* Для краткости я буду использовать «частный», а не «частный и / или защищенный».

- Ник

C #, C ++, дизайн-шаблоны, OOP, друг,
Похожие вопросы