Как реализовать интерфейс явно с помощью виртуального метода? - PullRequest
5 голосов
/ 26 июля 2010

Я не могу этого сделать

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    virtual void InterfaceA.MethodA()
    // Error: The modifier 'virtual' is not valid for this item
    {
    }
}

Где работает следующее

class ClassA : InterfaceA
{
    public virtual void MethodA()
    {
    }
}

Почему? Как это обойти?

Ответы [ 5 ]

8 голосов
/ 26 июля 2010

Я думаю, это потому, что когда член явно реализован, к нему нельзя получить доступ через экземпляр класса, а только через экземпляр интерфейса.

Поэтому создание чего-то «виртуального» действительно не имеет смысла в этом случае, поскольку виртуальное означает, что вы намереваетесь переопределить это в унаследованном классе. Реализация интерфейса явно и , делающая его виртуальным , была бы противоречивой. Это также может быть причиной того, что компилятор запрещает это.

Чтобы обойти это, я думаю, что ответ csharptest.net или Филиппа звучит так, как будто бы он добился цели

3 голосов
/ 26 июля 2010

Вы должны сделать что-то вроде этого:

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    void InterfaceA.MethodA()
    { MethodB(); }

    protected virtual void MethodB()
    { 
    }
}

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

interface IOrderDetails
{
    void PlaceOrder();
}

//Sometime later you extend with:
interface IOrderDetails2 : IOrderDetails
{
    void PlaceOrder(IUser user);
}

//Implementation
class Order : IOrderDetails, IOrderDetails2
{
    static readonly IUser AnonUser;

    void IOrderDetails.PlaceOrder()
    { OnPlaceOrder(AnonUser); }
    void IOrderDetails2.PlaceOrder(IUser user)
    { OnPlaceOrder(user); }

    protected virtual void OnPlaceOrder(IUser user)
    { 
    }
}

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

3 голосов
/ 26 июля 2010

В соответствии со спецификацией языка C #:

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

Вы можете "обойти" его, только вызвав виртуальный метод из явной реализации интерфейса.

0 голосов
/ 26 июля 2010

Нельзя использовать виртуальный модификатор с модификаторами static, abstract, private или override.модификатор по умолчанию является приватным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...