Ограничение свойства доступа в подклассе

#c# #properties #subclass

#c# #свойства #подкласс

Вопрос:

У меня есть класс с общедоступным свойством, к которому я хочу ограничить доступ _for_some_modules_. (Модули, которые используют этот класс, находятся в разных сборках, поэтому internal не помогает.)

Моей первой мыслью было создать подкласс и сделать средство доступа к производному свойству частным или защищенным, но это невозможно. Производное свойство должно иметь те же права доступа. (См. http://msdn.microsoft.com/en-us/library/75e8y5dd.aspx )

Есть предложения? Я предполагаю, что это обычная задача — создать более ограниченный вариант класса? Спасибо!

Комментарии:

1. Я не думаю, что это возможно — как только вы пересекаете границу сборки, все ставки отменяются.

2. могу ли я увидеть скелетную версию вашего класса? Обычно что-то подобное может быть решено с помощью более продуманного дизайна.

Ответ №1:

Вы можете использовать InternalsVisibleToAttribute , чтобы сделать internal члены класса видимыми для других сборок (скольких угодно). На странице документации приведен пример.

Ответ №2:

Я предполагаю, что это обычная задача — создать более ограниченный вариант класса?

Это не обычная задача, поскольку это нарушает принцип подстановки Лискова — вы не можете использовать подкласс так же, как вы использовали бы базовый класс в отношении свойства, к которому вы ограничиваете доступ. Вам следует подумать о рефакторинге вашей иерархии классов.

Вы могли бы решить проблему с помощью композиции — сделать класс A только внутренним и написать общедоступный класс-оболочку, который имеет член типа A и делегирует и контролирует доступ к A свойствам / методам.

Ответ №3:

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

Концепция, которую вы ищете, называется классом «friend» на других языках, но C # (намеренно) их не реализует. InternalsVisibleToAttribte максимально приближен, но применяется на уровне сборки, поэтому у вас может не сработать.

Без дополнительной информации о том, почему вы пытаетесь ограничить доступ таким образом, трудно предложить какие-либо хорошие альтернативы общего назначения. Модификаторы доступа, такие как public / private / etc, Не предназначены для использования в качестве механизма безопасности, поскольку отражение предоставит вам доступ для чтения / записи всего независимо. Это скорее подсказка потребителям относительно того, что безопасно использовать — общедоступные элементы обычно остаются стабильными в новых версиях, в то время как частные (подробности реализации) элементы с большей вероятностью изменятся.

Комментарии:

1. Спасибо за понимание (также для BrokenGlass ниже) о том, чтобы не делать подклассы более ограничительными.

2. Чего я пытаюсь достичь, так это создания подмножества класса модели. Класс модели был бы базовым классом, а производный класс — подмножеством (или представлением модели). Цель состоит в том, чтобы разные потребители видели только соответствующие части модели. Я хотел бы избежать копирования-вставки, чтобы получить соответствующие свойства для класса подмножества. (И я хотел бы избежать размышлений, потому что это может быть трудно понять другим разработчикам …)

Ответ №4:

Вы всегда можете сделать что-то вроде этого:

 class MyBaseClass
{
    protected string MyRestrictedProperty { get; set; }
}

class MyClass : MyBaseClass
{
    public string MyPublicProperty 
    {
        get { return MyRestrictedProperty;  }
        set { MyRestrictedProperty = value; }
    }
}