2009-12-08 4 views
25

Если у меня естьКак явным образом реализовать методы реализации интерфейса без явного литья?

public class AImplementation:IAInterface 
{ 
    void IAInterface.AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     ((IAInterface)this).AInterfaceMethod(); 
    } 
} 

Как звонить из AInterfaceMethod()AnotherMethod() без явного литья?

+0

В чем проблема с литой? – adrianm

+0

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

+2

Почему бы не сделать это наоборот? Переместите код из метода явного интерфейса в «обычный» метод. Затем просто позвольте всем методам (включая метод явного интерфейса) вызвать этот метод. – adrianm

ответ

-3

Не можете ли вы просто удалить «IAInterface». от подписи метода?

public class AImplementation : IAInterface 
{ 
    public void AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     this.AInterfaceMethod(); 
    } 
} 
+1

Тогда это не будет явная реализация. –

8

Пробовал это, и это работает ...

public class AImplementation : IAInterface 
{ 
    IAInterface IAInterface; 

    public AImplementation() { 
     IAInterface = (IAInterface)this; 
    } 

    void IAInterface.AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     IAInterface.AInterfaceMethod(); 
    } 
} 
0

Вы не можете, но если вам нужно сделать, это много можно определить хелпер удобства:

private IAInterface that { get { return (IAInterface)this; } }

Всякий раз, когда вы хотите вызвать метод интерфейса, который был реализован явно, вы можете использовать that.method() вместо ((IAInterface)this).method().

+1

Стоит отметить, что вам не нужно явно указывать здесь (поскольку существует неявное преобразование из 'this' в' IAInterface', которое реализуется). –

5

Вы можете ввести вспомогательную частную собственность:

private IAInterface IAInterface { get { return this; } } 

void IAInterface.AInterfaceMethod() 
{ 
} 

void AnotherMethod() 
{ 
    IAInterface.AInterfaceMethod(); 
} 
49

Ряд ответов сказать, что вы не можете. Они неверны. Существует множество способов сделать это без использования оператора трансляции.

Техника № 1: Используйте оператор «как» вместо оператора литья.

void AnotherMethod() 
{  
    (this as IAInterface).AInterfaceMethod(); // no cast here 
} 

Техника № 2: использовать неявное преобразование через локальную переменную.

void AnotherMethod() 
{  
    IAInterface ia = this; 
    ia.AInterfaceMethod(); // no cast here either 
} 

Техника # 3: написать метод расширения:

static class Extensions 
{ 
    public static void DoIt(this IAInterface ia) 
    { 
     ia.AInterfaceMethod(); // no cast here! 
    } 
} 
... 
void AnotherMethod() 
{  
    this.DoIt(); // no cast here either! 
} 

Техника # 4: Внедрить помощника:

private IAInterface AsIA() { return this; } 
void AnotherMethod() 
{  
    this.AsIA().IAInterfaceMethod(); // no casts here! 
} 
+5

Чтобы быть педантичным, он не просил не использовать «литой оператор», он просил «без явного кастинга», и я думаю, что, вообще говоря, оператор 'as' будет считаться« явным кастингом »(нет идеи если это верно в терминах определений спецификаций языка или вопрос в этом контексте даже бессмыслен). –

+1

Ну, семантика оператора литья и семантика оператора as совершенно разные, поэтому логическая ошибка состоит в их объединении. Подробнее см. Http://beta.blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx. –

+6

Я знаю, что это довольно старый, но я наткнулся на этот вопрос сегодня. Правильно ли я считаю, что «лучший» способ - это неявный бросок? Это дает лучшую защиту времени компиляции кода, я исправлю? Если бы я пошел либо с кастингом, либо с операцией «как» (что в действительности не имеет смысла в этом контексте, поскольку объект должен реализовывать интерфейс в первую очередь), я рискую попытаться применить к недопустимому интерфейсу, ошибка времени выполнения. Если я попытаюсь скрыть привязку к интерфейсу, который класс не реализует, я получаю вместо этого ошибку времени компиляции, причем намного лучше. – julealgon

0

Еще один способ (не лучший):

(this ?? default(IAInterface)).AInterfaceMethod(); 
1

И еще один способ (который является побочным Eric's Technique # 2, а также должна дать ошибку времени компиляции, если интерфейс не реализован)

 IAInterface AsIAInterface 
    { 
     get { return this; } 
    } 
Смежные вопросы