Проблема с интерфейсами

У меня есть интерфейс (называемый IMessage), который имеет метод Check(), класс реализует этот интерфейс

interface IMessage
{
    bool Check();
}

class NewClass : IMessage
{
    #region IMessage Members

    public bool Check()
    {
        //Some logic
    }
}

Это все хорошо. Проблема в том, что я не хочу, чтобы этот метод (Check()) был публичным, я хочу оставить его внутренним для ассемблера, но если я сделаю его внутренним, то компилятор скажет, что он не реализует интерфейс. Он должен быть общедоступным для реализации интерфейса. Что я могу сделать?

4 ответа

Решение

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

interface IMessage
{
    bool Check();
}

class NewClass : IMessage
{
    bool IMessage.Check()  { }
}

Тем не менее, любой, кто может бросить на IMessage интерфейс по-прежнему может вызывать Check(). Это не способ предотвратить вызов метода - только очистить открытый интерфейс класса. Если интерфейс является внутренним для вашей сборки, то только классы в этой сборке могут приводить к нему и вызывать метод.

В общем случае.NET не предлагает способ сделать только определенный метод интерфейса внутренним для реализации интерфейса. Это одна из областей, где вы можете рассмотреть абстрактный базовый класс - там вы можете создавать защищенные абстрактные методы, которые наследники могут реализовывать, не подвергая их внешним вызывающим объектам. Например:

abstract class MessageBase
{
    protected abstract bool Check();
}

class NewClass : MessageBase
{
    protected override bool Check() { ... }
}

Интерфейсы - все о том, как другие объекты взаимодействуют с этим типом объекта публичным способом. Если другие классы не должны получить доступ к Check() метод, то это не должно быть частью интерфейса.

Вот MSDN обсуждение этой темы, которое может быть полезным.

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

public abstract class Message
{
    internal abstract bool Check();
}

public class MyMessage : Message
{
    internal override bool Check()
    {
        // do stuff
    }
}
class NewClass : IMessage
{
    #region IMessage Members

    internal bool Check()
    {
        //Some logic
    }
    bool IMessage.Check()
    {
        return this.Check();
    }
}

Это обеспечивает внутреннюю реализацию, доступную только для классов в этой сборке, плюс явную реализацию интерфейса, которая позволяет вам соответствовать требованиям интерфейса. Для кода из внешней сборки, чтобы вызвать Check метод, это потребовало бы IMessage ссылка на ваш класс, а не NewClass ссылка.

Другие вопросы по тегам