2009-08-25 8 views
3

Ich versuche, eine einfache Schnittstelle zu entwickeln, die das Generieren von Schnelllisten aus Klassen ermöglicht. Grundsätzlich muss die Schnittstelle eine ID und einen Namen zurückgeben. Einige Klassen haben jedoch eine berechnete Name-Eigenschaft, die nur gelesen werden kann, andere verwenden nur eine Lese-/Schreib-Namenseigenschaft. Grundsätzlich ist mir egal, dass es einen Getter hat, es spielt keine Rolle, ob die Eigenschaft einen Setter hat. Wie kann ich diese Schnittstelle schreiben, um mit oder ohne Kompilierungsfehler umzugehen?Optionale Readonly-Eigenschaft in der VB.Net-Schnittstelle

Ich habe gelesen this question und nicht wirklich folgen, vielleicht bin ich nur dicht. Wenn ja, zeigen Sie mir bitte den Fehler meiner Wege :)

Antwort

5

Sieht aus wie die Antwort von der anderen Frage arbeiten: hier ist ein Beispiel:

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 

Der obige Ansatz wird tatsächlich in den Klassen das implementiert IReadWrite auch implementiert IReadOnly - so müssen Sie tatsächlich zu IReadWrite Downcast, um die Eigenschaft festzulegen.

Ein weiterer Ansatz, der dieses Problem vermeidet, erfordert aber ein wenig mehr Logik in den implementierenden Klassen und ihr Anrufer ist so etwas wie:

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 

Update: die Frage nach einziehe zu beantworten; "Downcasting" ist ein Begriff, der verwendet wird, um ein Objekt aus einer Oberklasse, einer Schnittstelle oder einer abstrakten Basisklasse Type in eine konkretere Type umzuwandeln. Das erste Beispiel oben definiert zwei Schnittstellen: IReadOnly und IReadWrite. Sie werden feststellen, dass IReadWriteIReadOnly implementiert, was bedeutet, dass Sie sowohl IReadWriteals auch Aufrufe an Objekte vornehmen können, die IReadWrite implementieren.

Da IReadWrite Arbeitsgeräte IReadOnly, IReadWrite wird als „Unterklasse“ von IReadOnly sein (obwohl „Subklasse“ mehr verwendet wird, genau eine Klasse zu beschreiben, die eine Basisklasse erbt, eher dann implementiert eine Schnittstelle - der Einfachheit halber sind sie fast das gleiche Konzept. Wenn IReadWrite eine Unterklasse von ist, dann ist die Umkehrung wahr - ist eine Superklasse von IReadWrite.

Zum Beispiel kann ich entweder eine Instanz von ReadWriteClass als Implementierung der Schnittstelle beschreiben:

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

Ich denke, die Frage – foson

+0

@foson für VB.NET-Code wurde gefragt: hoppla! Lemme es umschreiben :) – STW

+0

Danke für den Code, sorry bin so spät zurück zu bekommen. Könnten Sie mir ein Beispiel geben, wann und wie ich das Downcasting implementieren kann, ein Neuling zu sein, das ist neu für mich. Vielen Dank. – JoshPeltier