Сделайте методы/свойства видимыми для одного класса и скрытыми для других.

StackOverflow https://stackoverflow.com/questions/550268

  •  23-08-2019
  •  | 
  •  

Вопрос

у меня есть класс Server который говорит с серверным соединением для IRC.Он содержит список известных Users и создает их по мере необходимости.

У меня есть две проблемы, связанные с User сорт:

  1. Любой может создать экземпляр User.Я хочу только Server класс, чтобы иметь возможность это сделать.
  2. Если пользователь (вещь User описывает) меняет свое имя (или другую информацию, например, присоединенные каналы), Server класс может изменить его сам.Однако другие классы тоже могут!Я хочу запретить другим классам трогать эту информацию (сделав ее доступной только для них).

Как я могу решить эти две проблемы?В C++ эту проблему можно решить, используя friend ключевое слово и создание ctor и setName (и такое) частное.

Существует ли ключевое слово C#, которое может обеспечить доступность определенного метода для указанного класса?Это решило бы мою проблему.

Это было полезно?

Решение

Честно говоря, я нахожу friend доступ, исходящий из C++, является симптомом плохого дизайна.Лучше поправьте свой дизайн.

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

Если вас действительно это волнует, сделайте одно из следующих действий:

  • Сделайте пользователя интерфейсом.Сервер может создать экземпляр частного класса, который его реализует;или
  • Сделайте User внутренним классом Server без общедоступных конструкторов, чтобы только Сервер мог создавать его экземпляры.

Взломы видимости (одним из которых являются друзья в C++, а хорошие примеры — доступ к пакетам в Java) просто напрашиваются на неприятности, а не являются хорошей идеей.

Другие советы

Самый близкий в мире .NET к friend это internal видимость.

Обратите внимание: если ваши два класса находятся в разных сборках, вы можете использовать ВнутренностиVisibleTo атрибут, позволяющий одной сборке видеть внутренние части другой.

Перепроектирование иерархии классов, вероятно, является справедливым решением этой проблемы.Потому что мне кажется, что вам действительно нужен класс User, доступный только для чтения, если он существует вне класса Server.

Я бы, наверное, сделал что-то вроде этого:

// An abstract base class. This is what I'd use outside the 
// Server class. It's abstract, so it can't be instantiated
// on its own, and it only has getters for the properties. 
public abstract class User
{
   protected User()
   {
   }

   public string Name { get;}
   // Other get-only properties
}

public class ServerUser : User
{
   public ServerUser()
   {
   }

   public string Name { get; set;}
   // Other properties. 
}

Затем класс Server создаст классы ServerUser, а пользователь класса Server изменит свойства классов ServerUser (например, изменит имя пользователя), но откроет только классы User для внешнего мира.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top