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

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

1 голос
/ 26 декабря 2009

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

interface IMessage
{
    bool Check();
}

class NewClass : IMessage
{
    #region IMessage Members

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

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

Ответы [ 4 ]

8 голосов
/ 26 декабря 2009

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

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() { ... }
}
2 голосов
/ 26 декабря 2009

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

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

1 голос
/ 26 декабря 2009

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

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

public class MyMessage : Message
{
    internal override bool Check()
    {
        // do stuff
    }
}
1 голос
/ 26 декабря 2009
class NewClass : IMessage
{
    #region IMessage Members

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

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

...