Я обычно переводил случаи, когда ключевое слово friend кажется удобным в шаблоне, где сам класс определяет, какие классы могут его создавать, не нарушая надлежащего OO-дизайна.
Идея состоит в том, что класс, который хочет контролировать, кто может создавать экземпляр, предлагает дружбу классам, которым разрешено получать экземпляр. Например, класс InControl позволяет классам ChosenOne и ChosenTwo получать экземпляры InControl.
Класс «избранный» (то есть ChosenOne или ChosenTwo) может «вовлечь» дружбу, предлагаемую InControl, с помощью экземпляра самой себя (friendship.engage (this)), и дружба, в свою очередь, может «принять» этот экземпляр, предоставив это экземпляр InControl (friend.accept (новый InControl())).
Настоящая дружба осуществляется с помощью вложенного единственного экземпляра класса Дружбы. Дружба ограничивается «выбранными» классами, используя общий интерфейс IFriendship, где T является выбранным классом. В свою очередь, каждому «выбранному» классу необходимо внедрить общий интерфейс IFriendable с T, являющимся InControl, чтобы иметь возможность получить экземпляр InControl.
Класс InControl имеет частный конструктор, чтобы избежать создания экземпляра кто-либо еще, кроме друзьями:
public interface IFriendable<T>
{
void accept(T friend);
}
public interface IFriendship<T>
{
void engage(T friend);
}
public class ChosenOne : IFriendable<InControl>
{
private InControl _friend { get; set; }
private ChosenOne()
{
InControl.friendship.engage(this);
}
public void accept(InControl friend)
{
_friend = friend;
}
}
public class ChosenTwo : IFriendable<InControl>
{
private InControl _friend { get; set; }
private ChosenTwo()
{
InControl.friendship.engage(this);
}
public void accept(InControl friend)
{
_friend = friend;
}
}
public class InControl
{
public interface IFriendship : IFriendship<ChosenOne>, IFriendship<ChosenTwo> { }
public static IFriendship friendship { get { return Friendship.instance; } }
private class Friendship : IFriendship
{
static Friendship()
{
}
internal static readonly Friendship instance = new Friendship();
public void engage(ChosenOne friend)
{
friend.accept(new InControl());
}
public void engage(ChosenTwo friend)
{
friend.accept(new InControl());
}
}
private InControl()
{
}
}
Не. Придумайте лучший дизайн, кому нужны друзья? Это всегда было признаком вопиющего кода на C++. Как альтернативное предложение, возможно, подумайте об использовании интерфейсов и явной реализации http://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx – Mick
@Mick Да, я полностью согласен с вами. Но я просто думаю об этом из любопытства и цели исследования/исследования, просто чтобы узнать, что мы можем получить от C#. –
Я думаю, что Андерс Хейлсберг был бы полностью осведомлен о всех конструкциях, доступных на C++, и сделал преднамеренные решения о том, как помочь в продвижении хороших практик на C#, а также о том, какие конструкции на C++ удаляются из C# для устранения в плохих практиках, вероятно, попал в последнюю категорию. Это признак плохого сочетания дизайна, когда я сказал, что лучший дизайн я бы назвал менее тесно связанным дизайном. Ваш ответ ниже - иллюстрация чрезмерной связи. – Mick