2009-07-03 10 views
16

Я получаю ошибку компиляции из следующего свойства.
Ошибка:Модификаторы доступа на элементах интерфейса в C#

«Модификатор„общественность“не действует для этого элемента»

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

но если я удалю IWorkItemControl компилирует нормально.

Почему я получаю эту ошибку и в чем разница наличия/отсутствия имени интерфейса в сигнатуре?

ответ

41

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

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 

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

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

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

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

interface IOne { 
    bool Property { get; } 
} 

interface ITwo { 
    string Property { get; } 
} 

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

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

0

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

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

+1

Это не очень сильная причина, так как вам по-прежнему приходится вручную указывать публикацию для всех неявно реализованных членов. Если бы это было так, компилятор мог автоматически принять их как публичные. –

+0

Это неправильно, так как вы можете иметь внутренние интерфейсы. –