2010-03-02 9 views
5

Hemos una interfaz, que puede ser extremadamente simplificada como:protegidas fijado en VB.Net para una propiedad definida en una interfaz

public interface IPersistable<T> 
{ 
    T Id { get; } 
} 

mayoría de los lugares que implementan la interfaz desea tenerlo de manera que hay una protegida o conjunto privado en esa propiedad, es decir, en C#:

public class Foo : IPersistable<int> 
{ 
    public int Id { get; protected set; } 
} 

sin embargo, no se puede conseguir cualquier código de ejemplo para compilar VB.Net que sigue el mismo patrón, mientras que todavía implementación de la interfaz, por lo que:

Public Class Foo 
    Implements IPersistable(Of Integer) 

    Public Property Id() As Integer Implements IPersistable(Of Integer).Id 
     Get 
      Throw New NotImplementedException() 
     End Get 
     Protected Set(ByVal value As Integer) 
      Throw New NotImplementedException() 
     End Set 
    End Property 
End Class 

... no se compilará, pero esto sería:

Public Class Foo 
    Public Property Id() As Integer 
     Get 
      Throw New NotImplementedException() 
     End Get 
     Protected Set(ByVal value As Integer) 
      Throw New NotImplementedException() 
     End Set 
    End Property 
End Class 

Soy consciente de que este ejemplo es demasiado trivial, y que, posiblemente, puede lograrse mejor a través de constructores protegidas, pero me interesa si puede ser hecho de esta manera?

[EDIT:] ... y obviamente, si un tipo desea utilizar XMLSerialization, entonces las propiedades necesitarían ser de lectura/escritura pública o los tipos requerirían serializadores personalizados escritos para cada uno.

Básicamente, veo que la interfaz debe definir la accesibilidad mínima, pero VB la interpreta como la accesibilidad exacta.

+1

+1 Me encontré con la misma situación antes de darme cuenta de que VBNET no lo permite. –

Respuesta

6

Sí, tendrá que implementar la interfaz literalmente. Una posible solución consiste en publicar la propiedad de la clase con otro nombre:

Public Class Foo 
    Implements IPersistable(Of Integer) 
    Private m_Id As Integer 

    Public ReadOnly Property Id() As Integer Implements IPersistable(Of Integer).Id 
    Get 
     Return m_Id 
    End Get 
    End Property 

    Protected Property IdInternal() As Integer 
    Get 
     Return m_Id 
    End Get 
    Set(ByVal value As Integer) 
     m_Id = value 
    End Set 
    End Property 
End Class 

declarar la propiedad Overridable si la intención de anularlo en las clases derivadas.

+0

+1 VBNET no permite dicho cambio de modificador en el getter y setter de propiedades. Necesita volver a publicar el colocador en otra propiedad o tener acceso a su campo privado que, por supuesto, tendrá un modificador diferente de privado. Esto se debe a que la interfaz exige implementarse tal como está escrita. Por lo tanto, si marca su propiedad Id como pública, sin mencionarla como ReadOnly, tendrá que hacer Get y Set Public. –

+0

Aceptado, como ahora lo he encontrado, este es un artículo de la lista de deseos: http://stackoverflow.com/questions/2362381/protected-set-in-vb-net-for-a-property-defined-in-an-interface/2365193 # 2365193 –

1

Actualmente no es compatible con el idioma, ni lo hará en Visual Basic 10 (es decir, la versión con Visual Studio 2010). Hay un wishlist item for exactly this. Hasta entonces, las soluciones alternativas sugeridas por nobugz son la única opción.

0

Las propiedades de la interfaz solo pueden implementarse mediante propiedades de clase que coincidan. Esto es cierto tanto en vb.net como en C#. Lo que es diferente en los dos idiomas es que la característica implícita de implementación de interfaz de C# definirá automáticamente una propiedad de solo lectura o de solo escritura para implementar una interfaz si está disponible una propiedad pública de lectura y escritura del mismo nombre.

1

A partir del Visual Basic 14, su primer ejemplo de código VB compila bien.

Cuestiones relacionadas