2009-08-25 12 views
3

J'essaie de développer une interface simple permettant de générer des listes rapides à partir de classes. Fondamentalement, l'interface doit retourner un identifiant et un nom. Cependant, certaines classes ont une propriété de nom calculée qui est en lecture seule, d'autres utilisent simplement une propriété de nom en lecture/écriture. Fondamentalement, tout ce qui m'importe c'est qu'il a un getter, peu importe si la propriété a un setter. Comment puis-je écrire cette interface pour gérer ou sans lancer des erreurs de compilation?Propriété Readonly facultative dans l'interface VB.Net

J'ai lu this question et ne l'ai pas vraiment suivi, peut-être que je suis juste dense. Si oui, s'il vous plaît me montrer l'erreur de mes manières :)

Répondre

5

On dirait que la réponse de l'autre question fonctionnera: voici un échantillon:

Public Interface IReadOnly 
    ReadOnly Property Name() As String 
End Interface 

Public Interface IReadWrite 
    Inherits IReadOnly 

    Overloads Property Name() As String 

End Interface 

Public Class ReadOnlyClass 
    Implements IReadOnly 

    Private _Name 
    Public ReadOnly Property Name() As String Implements IReadOnly.Name 
     Get 
      Return _Name 
     End Get 
    End Property 
End Class 

Public Class ReadWriteClass 
    Implements IReadWrite 

    Private ReadOnly Property ReadOnly_Name() As String Implements IReadOnly.Name 
     Get 
      Return Name 
     End Get 
    End Property 

    Private _Name As String 
    Public Overloads Property Name() As String Implements IReadWrite.Name 
     Get 
      Return _Name 
     End Get 
     Set(ByVal value As String) 
      _Name = value 
     End Set 
    End Property 
End Class 

L'approche ci-dessus entraînera effectivement dans les classes implémenter IReadWrite implémentant également IReadOnly - vous aurez donc besoin d'être redirigé vers IReadWrite pour définir la propriété.

Une autre approche, ce qui évite cette question, mais nécessite un peu plus logique dans les classes implémentant et leur appelant de quelque chose comme:

Public Interface ISometimesWritable 
    Property Name() As String 
    ReadOnly Property AllowNameEdit() As Boolean 
End Interface 

Public Class ReadOnlyClass 
    Implements ISometimesWritable 

    Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit 
     Get 
      Return False 
     End Get 
    End Property 

    Private _Name As String 
    Public Property Name() As String Implements ISometimesWritable.Name 
     Get 
      Return _Name 
     End Get 
     Set(ByVal value As String) 
      Throw New NotSupportedException("Name cannot be set when AllowNameEdit is False") 
     End Set 
    End Property 
End Class 

Public Class ReadWriteClass 
    Implements ISometimesWritable 

    Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit 
     Get 
      Return True 
     End Get 
    End Property 

    Private _Name As String 
    Public Property Name() As String Implements ISometimesWritable.Name 
     Get 
      Return _Name 
     End Get 
     Set(ByVal value As String) 
      _Name = value 
     End Set 
    End Property 
End Class 

Mise à jour: Pour répondre à la question au sujet de coulée en descente; "downcasting" est un terme utilisé pour décrire la coulée d'un objet à partir d'une superclasse, d'une interface ou d'une classe de base abstraite Type dans un Type plus concret.

Par exemple, le premier exemple ci-dessus définit deux interfaces: IReadOnly et IReadWrite. Vous remarquerez que IReadWrite implémente IReadOnly, ce qui signifie que vous pouvez effectuer à la fois IReadWriteetIReadOnly appels aux objets qui implémentent IReadWrite.

Depuis IReadWrite met en œuvre IReadOnly, IReadWrite est dit être un « sous-classe » de IReadOnly (bien que « sous-classe » est plus précisément utilisée pour décrire une classe qui hérite une classe de base, plutôt que implémente une interface - pour des raisons de simplicité, ils sont à peu près le même concept). Si IReadWrite est une sous-classe de IReadOnly, alors l'inverse est vrai-- IReadOnly est un super-classe de IReadWrite.

Par exemple, je peux décrire une instance de ReadWriteClass comme une implémentation de l'interface soit:

Public Sub SomeMethod() 
    dim readOnlyInstance as IReadOnly = new ReadWriteClass() 
    Console.WriteLine(readOnlyInstance.Name) 

    ' The following line won't compile, since we're communicating with ReadWriteClass as an instance of IReadOnly 
    'readOnlyInstance.Name = "Santa Clause" 

    ' Here we downcast the variable to reference it by it's other interface, IReadWrite 
    dim readWriteInstance = DirectCast(readOnlyInstance, IReadWrite) 

    ' Now we can both Get and Set the value of Name 
    readWriteInstance.Name = "John Doe" 
    Console.WriteLine(readWriteInstance.Name) 

    ' Note that in the above example we created *one* instance of ReadWriteClass 
    ' and have provided two variables/references to the same underlying object. 
    Console.WriteLine(readOnlyInstance.Name) ' <-- note that this should return "John Doe" 

End Sub 
+0

Je pense que la question demandait le code VB.NET – foson

+0

@foson: oups! Lemme réécrire :) – STW

+0

Merci pour le code, désolé je suis tellement en retard pour y revenir. Pourriez-vous me donner un exemple de quand et comment mettre en œuvre le downcasting, étant un débutant, c'est nouveau pour moi. Merci. – JoshPeltier