2017-01-23 8 views
1

У меня есть следующий интерфейс иерархии:Не удается передать суб-интерфейс в качестве параметра в C#

public interface IActor { ... } 
public interface IHealthUser : IActor { ... } 

и третий интерфейс:

public interface IAction { void Perform(IActor caster) } 

Почему следующий не законно и я могу обойти это как-то?

public class HealthPotion : IAction 
{ 
    public void Perform(IHealthUser caster) { ... } 
} 
+0

@ZoharPeled «„HealthPotion“не реализует элемент«IAction. Выполните (IActor) ' – user1323245

ответ

6

В договоре, определенном IAction, указано, что вы можете Perform действие на любые IActor. Любые IActor. Не только IHealthUser. То, что пытается выполнить ваш HealthPotion, - это реализовать только подмножество IAction, что означает выполнение его задачи только на подмножестве IActor. Это не то, что говорит интерфейс IAction.

Если вы хотите специфический IAction, чтобы иметь возможность ограничить тип IActor это относится, вы можете сделать это с помощью общих ограничений:

public interface IAction<TAppliesTo> where TAppliesTo : IActor 
{ 
    void Perform(TAppliesTo appliesTo); 
} 

public class UniversalAction : IAction<IActor> 
{ 
    public void Perform (IActor anyone) {} 
} 

public class HealthPotion : IAction<IHealthUser> 
{ 
    public void Perform (IHealthUser healthUserOnly){} 
} 
+1

Конечно, я застрял в мышлении «IHealthUser - это производный интерфейс, он должен работать!», Когда то, что я на самом деле делал, делало реализацию IAction более ограниченной. Вы положили ее хорошо, а общий чудеса опционной работы. – user1323245

2

Вам необходимо реализовать ту же подпись, что и ваш интерфейс. Вы используете IActor в интерфейсе, но затем используете IHealthUser при реализации Интерфейс IAction. Вы должны выполнить команду Выполнить с параметром IActor с параметром . Его можно назвать, однако, классом, который реализует IHealthUser.

Смежные вопросы