C # внутренний геттер, защищенный сеттер с внутренним параметром класса - PullRequest
7 голосов
/ 07 января 2010

У меня была проблема с желанием, чтобы свойство имело внутренний геттер и защищенный сеттер, как описано в этом вопросе , и я подумал, что решил это, выполнив следующее:

public class Accessor : AccessorBase
{
    private Connection _connection;

    protected void setConnection(Connection value)
    {
        _connection = value;
    }

    internal Connection GetConnection()
    {
        return _connection;
    }
    ...
}

Однако теперь я получаю эту ошибку:

Непоследовательная доступность: тип параметра «Соединение» менее доступен, чем метод «setConnection (Соединение)»

Это потому, что у меня internal class Connection. Я бы не стал делать Connection общедоступным классом, в то время как Accessor нужно, чтобы был общедоступным, так как я могу обойти эту ошибку, сохраняя при этом внутренний геттер и защищенный сеттер?

Ответы [ 7 ]

9 голосов
/ 07 января 2010

К сожалению, C # не поддерживает «внутренние и защищенные» модификаторы доступа (поддерживаются только «внутренние или защищенные»), что означает, что любые protected члены виден снаружи сборки и не может использовать внутренний тип.
Использование internal вместо protected было бы наиболее логичным решением.

И вы можете голосовать в Microsoft Connect , чтобы когда-нибудь его можно было добавить в C #.

Обновление: начиная с C # 7.2 для этого можно использовать private protected.

5 голосов
/ 07 января 2010

Создайте открытый интерфейс IConnection, который реализует ваш внутренний объект Connection. Ваши методы GetConnection и SetConnection принимают и возвращают IConnection вместо Connection.

Basic SOLID принципы снова побеждают.

2 голосов
/ 07 января 2010

... все защищенные участники видны вне сборки и не может использовать внутренний тип.

- Пент Плоомпуу ответ

Один из способов обойти это - сделать Connection общедоступным, в то же время сделав все его методы экземпляра и конструкторы внутренними.

1 голос
/ 07 января 2010

Если класс Connection является внутренним, производный класс Accessor не сможет вызывать защищенное setConnection, поскольку у него нет доступа к Connection.

Если setConnection должен быть защищен, соединение должно быть общедоступным.

0 голосов
/ 07 января 2010

Coincoin верна , Accessor - это публичный класс, который любой может извлечь из него, это означает также и из другой сборки. Этот производный класс теперь имеет защищенный метод, которому необходимо передать внутренний (из другой сборки) класс. Это никогда не сработает.

Вам нужно либо сделать Accessor внутренним, либо Connection общедоступным, либо еще лучше следовать Randolphos answer

Вот пример кода проблемы

Сборка 1

//this class is only visible in Assembly 1
internal class Connection
{

}
public class Accessor
{
   protected void SetConnection(Connection con) { }
}

Сборка 2 - имеет ссылку на Сборку 1

//possible because Accessor is public
DerivedAccessor : Accessor
{
   void SomeMethod()
    {
        this.SetConnection(????) // you can't pass Connection, its not visible to Assembly2 
    }
}
0 голосов
/ 07 января 2010

Ты не можешь этого сделать. Поскольку Connection является внутренним, некоторый класс, производный от Accessor из другой сборки, не сможет увидеть Connection, даже если вы отметите установщик как protected internal, это ничего не решит.

Ваша единственная надежда - сделать класс Connection общедоступным.

0 голосов
/ 07 января 2010

Извините, если вам нужна точная настройка, вам нужно сделать ваш класс Connection общедоступным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...