2015-01-07 23 views
1

У меня есть ниже классовая структура:Преобразования родовых типов

public class FirstContextController : AFirstContextController 

public abstract class AFirstContextController : ABaseController<AFirstContextView> 

public abstract class ABaseController<TView> where TView : ABaseView 

public abstract class AFirstContextView : ABaseContextView 

public abstract class ABaseContextView : ABaseView 

public abstract class ABaseView : UserControl 

Теперь я создаю экземпляр моего контроллера:

AFirstContextController firstContextController = new FirstContextController(); 

и нужно возвратить его от метода:

public static ABaseController<ABaseContextView> GetContextController(...) 
{ 
    return firstContextController; 
} 

Но затем я получаю ошибку:

Не может неявно преобразовать тип 'AFirstContextController' к 'ABaseController'

Так я tryied много литья (например):

return (ABaseController<AFirstContextView>)firstContextController; 

return (ABaseController<ABaseContextView>)((ABaseController<AFirstContextView>)firstContextController); 

Но все-таки получить аналогичные ошибки по конверсии. Какое преобразование я должен применить, чтобы вернуть его?

ответ

4

Для этого вам потребуется интерфейс, полученный от ABaseController<ABaseContextView>.

Это связано с дисперсией и ковариацией. Рид больше об этом на MSDN: Covariance and Contravariance in Generics.

Вам необходимо будет пометить ABaseContextViewout в определении вашего интерфейса, поэтому подпись должна быть чем-то вроде IBaseController<out ABaseContextView>.

Пример:

public abstract class ABaseController<TView> : IBaseController<TView> where TView : ABaseView 
{ 
    public void SomeMethod() { } 
} 

И интерфейс:

public interface IBaseController<out TView> where TView : ABaseView 
{ 
    void SomeMethod(); 
} 

Тогда ваш текущий метод следует читать:

public static IBaseController<ABaseContextView> GetContextController(...) 
{ 
    return firstContextController; 
} 
+0

ли я правильно understanded вас - я должен изменить свой метод определение из: public static ABaseController GetContextController (...) для публичного статического ABaseController <** out ** ABaseContextView> GetContextController (...)? Я сделал это так, но теперь получаю сообщение об ошибке: ** Недопустимый модификатор отклонения. В качестве варианта можно указать только параметры интерфейса и типа делегата. ** – user3057544

+0

Частично да, вы должны также создать интерфейс, так как классы не могут быть ковариантными. –

+0

Но это проблема, из-за которой я не могу изменить свой абстрактный класс на интерфейс, потому что он происходит из UserControll. Итак, есть ли другой способ достижения моей цели - иметь общий или «общий» метод, который может возвращать контроллеры из вышерасположенной структуры? – user3057544

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