C# внутренний метод считывания, защищенный метод set с внутренним параметром класса

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

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 потребности быть общедоступным, поэтому как я могу обойти эту ошибку, все еще поддерживая внутренний метод считывания и защищенный метод set?

7
задан Community 23 May 2017 в 12:26
поделиться

7 ответов

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

-- Ответ Плумпуу

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

2
ответ дан 6 December 2019 в 11:49
поделиться

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

Основные принципы СОЛИД снова выигрывают.

5
ответ дан 6 December 2019 в 11:49
поделиться

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

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

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

Assembly 1

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

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

Assembly 2 - имеет ссылку на Assembly 1

//possible because Accessor is public
DerivedAccessor : Accessor
{
   void SomeMethod()
    {
        this.SetConnection(????) // you can't pass Connection, its not visible to Assembly2 
    }
}
0
ответ дан 6 December 2019 в 11:49
поделиться

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

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

.
0
ответ дан 6 December 2019 в 11:49
поделиться

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

0
ответ дан 6 December 2019 в 11:49
поделиться

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

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

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

9
ответ дан 6 December 2019 в 11:49
поделиться

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

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

1
ответ дан 6 December 2019 в 11:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: