que polimorfismo interfaces herencia clases abstractas c# vb.net

interfaces - polimorfismo c#



La clase VB.NET hereda una clase base e implementa un problema de interfaz(funciona en C#) (7)

Estoy intentando crear una clase en VB.NET que hereda una clase abstracta base y también implementa una interfaz. La interfaz declara una propiedad de cadena llamada Descripción. La clase base contiene una propiedad de cadena llamada Descripción. La clase principal hereda la clase base e implementa la interfaz. La existencia de la propiedad Descripción en la clase base cumple los requisitos de interfaz. Esto funciona bien en C # pero causa problemas en VB.NET.

Primero, aquí hay un ejemplo del código C # que funciona:

public interface IFoo { string Description { get; set; } } public abstract class FooBase { public string Description { get; set; } } public class MyFoo : FooBase, IFoo { }

Ahora aquí está la versión de VB.NET que da un error de compilación:

Public Interface IFoo Property Description() As String End Interface Public MustInherit Class FooBase Private _Description As String Public Property Description() As String Get Return _Description End Get Set(ByVal value As String) _Description = value End Set End Property End Class Public Class MyFoo Inherits FooBase Implements IFoo End Class

Si hago que la clase base ( FooBase ) implemente la interfaz y añada Implements IFoo.Description a la propiedad, todo está bien, pero no quiero que la clase base implemente la interfaz.

El error del compilador es:

La clase ''MyFoo'' debe implementar ''Descripción de la propiedad () como cadena'' para la interfaz ''IFoo''. La implementación de la propiedad debe tener especificadores ''ReadOnly'' o ''WriteOnly'' que coincidan.

¿Puede VB.NET no manejar esto, o necesito cambiar mi sintaxis en alguna parte para que esto funcione?


De una forma u otra, debe especificar los detalles de implementación de la interfaz IFoo.

¿Qué hay de esta simple opción?

Public Class MyFoo Inherits FooBase Implements IFoo Overloads Property Description() As String Implements IFoo.Description Get Return MyBase.Description End Get Set(ByVal value As String) MyBase.Description = value End Set End Property End Class


Este es un problema extraño y muestra claramente una diferencia entre los compiladores C # y VB.NET. Sugiero que implemente la interfaz en la clase base abstracta, ya que esto hará que el compilador de VB.NET esté contento y, en el momento de la ejecución, su clase secundaria aún tendrá metadatos que indiquen que de hecho implementa IFoo .

¿Hay alguna razón específica para que la clase hija sea la que declare que implementa la interfaz?


Lo siento si llego tarde a la fiesta, y me disculpo si esta funcionalidad solo se introdujo en .NET 4, pero lo siguiente es posible (ahora)

Public Interface IFoo Property Description() As String End Interface Public MustInherit Class FooBase Implements IFoo Public MustOverride Property Description As String Implements IFoo.Description End Class Public Class MyFoo Inherits FooBase Private _description As String Public Overrides Property Description As String Get Return _description End Get Set(value As String) _description = value End Set End Property End Class


No puedo comentar la respuesta de MA Hanin debido a mi representante, pero recomendaría una pequeña modificación para evitar las advertencias del compilador sobre la ocultación de métodos base, suponiendo que no desea o no puede anular la propiedad en la clase base.

Public Class MyFoo Inherits FooBase Implements IFoo Private Property IFoo_Description() As String Implements IFoo.Description Get Return Me.Description End Get Set(ByVal value As String) Me.Description = value End Set End Property End Class


VB requiere que la propiedad de implementación declare la implementación. Esto se debe a lo que realmente considero una buena característica de VB que a veces extraño en C #, que puede cambiar el nombre del miembro que implementa el miembro de la interfaz.

Por lo tanto, la única manera de hacer que esto funcione sin implementar IFoo.Description en FooBase es declarar Description Overridable y luego definir MyFoo como:

Public Class MyFoo Inherits FooBase Implements IFoo Public Overrides Property Description() As String Implements IFoo.Description Get Return MyBase.Description End Get Set(ByVal value As String) MyBase.Description = value End Set End Property End Class


VB.NET no es compatible con la implementación implícita. También encontré este problema y tuve muchos problemas.

Cuando trabajas con clases generadas (entidades, etc.) donde tienes que declarar explícitamente Implements IFoo , lo hace imposible en absoluto.

Por lo tanto , envié una conexión a Microsoft y espero que voten y la próxima versión de VB mejorará el compilador para que sea más inteligente.


Overridable marcar su propiedad como Overridable o MustOverride en la clase base y luego puede MustOverride en la clase secundaria:

Public MustInherit Class FooBase Private _Description As String Public Overridable Property Description() As String Get Return _Description End Get Set(ByVal value As String) _Description = value End Set End Property End Class Public Class MyFoo Inherits FooBase Implements IFoo Public Overrides Property Description() As String Implements IFoo.Description Get Return MyBase.Description End Get Set(ByVal value As String) MyBase.Description = value End Set End Property End Class

Editar Esto es en respuesta a lo que @MA Hanin publicó. Ambas soluciones funcionan pero es importante entender las ramificaciones de cada una. Imagine el siguiente código:

Dim X As FooBase = New MyFoo() Trace.WriteLine(X.Description)

¿Qué sale de X.Description? Usando el Overridable obtendrá la llamada a la clase secundaria mientras usa el método de Sobrecarga, recibirá la llamada a la clase base. Ninguno de los dos está bien o mal, solo es importante entender las consecuencias de la declaración. Usando el método de Sobrecarga, tiene que actualizar para obtener la implementación del niño:

Trace.WriteLine(DirectCast(X, MyFoo).Description)

Si solo llamas a MyBase.Description desde la clase de niños, la pregunta es discutible, pero si alguna vez cambias la definición de la clase de niños entonces solo necesitas asegurarte de que entiendes lo que está pasando.