Модификаторы доступа на интерфейсных участниках в C#

Для нахождения всех типов в блоке, которые реализуют интерфейс IFoo:

var results = from type in someAssembly.GetTypes()
              where typeof(IFoo).IsAssignableFrom(type)
              select type;

Примечание, что предложение Ryan Rinaldi было неправильным. Это возвратит 0 типов. Вы не можете записать

where type is IFoo

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

кроме того, предложение Adam Wright, которое в настоящее время отмечается как ответ, является неправильным также, и по той же причине. Во времени выполнения Вы будете видеть, что 0 типов возвращаются, потому что вся Система. Экземпляры типа не были конструкторами IFoo.

16
задан River 18 October 2017 в 03:15
поделиться

2 ответа

Явная реализация интерфейса не позволяет вам указывать какие-либо модификаторы доступа. Когда вы реализуете член интерфейса явно (указав имя интерфейса перед именем члена), вы можете получить доступ к этому члену только с помощью этого интерфейса . В основном, если вы это сделаете:

System.Collections.Specialized.StringDictionary IWorkItemControl.Properties
{
    get { return properties; }
    set { properties = value; }
}

Вы не сможете:

MyClass x = new MyClass();
var test = x.Properties; // fails to compile
// You should do:
var test = ((IWorkItemControl)x).Properties; // accessible through the interface

Есть несколько вариантов использования EII. Например, вы хотите предоставить своему классу метод Close , чтобы освободить полученные ресурсы, но вы все равно хотите реализовать IDisposable . Вы можете сделать:

class Test : IDisposable {
    public void Close() {
        // Frees up resources
    }
    void IDisposable.Dispose() {
        Close();
    }
}

Таким образом, потребители класса могут только вызвать Close напрямую (и они даже не увидят Dispose в списке Intellisense), но вы все равно можете использовать Тестируйте класс везде, где ожидается IDisposable (например, в с использованием оператора ).

Другой вариант использования EII - это предоставление различных реализаций члена интерфейса с одинаковым именем для двух интерфейсов:

interface IOne {
   bool Property { get; }
}

interface ITwo {
   string Property { get; }
}

class Test : IOne, ITwo {
   bool IOne.Property { ... }
   string ITwo.Property { ... }
}

Как вы видите, без EII это даже невозможно для реализации обоих интерфейсов этого примера в одном классе (поскольку свойства различаются только типом возвращаемого значения). В других случаях вы можете намеренно обеспечить различное поведение для отдельных представлений класса через разные интерфейсы.

41
ответ дан 30 November 2019 в 16:19
поделиться

Все элементы интерфейса должны быть общедоступными. В конце концов, интерфейс является общедоступным представлением объекта.

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

0
ответ дан 30 November 2019 в 16:19
поделиться
Другие вопросы по тегам:

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