c# - puede - que es una interfaz en programacion
Interfaz derivada con miembro derivado de la interfaz (2)
Tengo 2 interfaces base, IViewBase (que todas las vistas implementarán) e IPresenterBase (que implementarán todos los presentadores):
public interface IViewBase { }
public interface IPresenterBase
{
IViewBase View { get; set; }
}
Luego creé una nueva interfaz ILogPresenter que deriva de IPresenterBase e ILogView que deriva de IViewBase:
public interface ILogPresenter : IPresenterBase { }
public interface ILogView : IViewBase{ }
Cuando creo una clase que implementa ILogPresenter,
public class LogPresenter: ILogPresenter
{
public ILogView View { get; set; }
}
Me sale un error:
''LogPresenter'' no implementa el miembro de la interfaz ''IPresenterBase.View''. ''LogPresenter.View'' no puede implementar ''IPresenterBase.View'' porque no tiene el tipo de retorno coincidente de ''Views.IViewBase''.
No puedo establecer el tipo de retorno de LogPresenter.View en ILogView, que se deriva de IViewBase? Me gustaría implementar ILogPresenter con una IView diferente que se deriva de IViewBase.
Probablemente quiera usar genéricos aquí:
public interface IViewBase { }
public interface IPresenterBase<T> where T : IViewBase
{
T View { get; set; }
}
entonces:
public interface ILogPresenter : IPresenterBase<ILogView> { }
public interface ILogView : IViewBase{ }
Aparte de los tipos de retorno covariantes que no son compatibles con C # (lo que causaría un problema incluso con un getter), tiene un problema fundamental en el original. Yo podría hacer:
IPresenterBase foo = new LogPresenterImpl();
foo.View = new SomeOtherView();
donde IVewBase
implementó IVewBase
pero no ILogView
. ¿Cómo esperas que tu propiedad haga frente a eso?
La versión genérica anterior resuelve esto al permitir que un presentador exprese qué tipo de vista está presentando.
Puedes hacer esto con genéricos:
public interface IViewBase { }
public interface IPresenterBase<T> where T : IViewBase
{
T View { get; set; }
}
public interface ILogPresenter : IPresenterBase<ILogView> { }
public interface ILogView : IViewBase { }
public class LogPresenter : ILogPresenter
{
public ILogView View { get; set; }
}