I have a overlapping data objects that need to be given to at least one, possibly more, of several calculation methods to produce a common data object.
I think this is best solved by implementing both covarriance contravariance but I haven't been able to wrap my head around how what that would look like so I am open to other suggestions. In reality Animal/IAnimal and Noise have a lot of data properties so I'd like to avoid mapping them in constructors as much as possible.
Public Class Noise
Public Property Sound() As String
Public Sub Listen()
Console.WriteLine(sound)
End Sub
End Class
Public Interface IAnimal
Function Speak() As Noise
Property Name() As String
End Interface
Public Class Dog
Implements IAnimal
Public Function Speak() As Noise Implements IAnimal.Speak
return new Noise() with { .Sound = "Bark" }
End Function
Public Property Name As String Implements IAnimal.Name
End Class
Public Class Cat
Implements IAnimal
Public Function Speak() As Noise Implements IAnimal.Speak
return new Noise() with { .Sound = "Meow" }
End Function
Public Property Name As String Implements IAnimal.Name
End Class
The below test produces the right output, and also works if IAnimal were an abstract base class with abstract function speak. If I understand correctly this means the covariant behavior is achieved, since it is kind of what you expect from inheritance.
Public Sub ListenToAnimalsTest()
dim spot = new Dog() With {.Name = "Spot" }
dim kitty = new Cat() With {.Name = "Kitty" }
Dim animalList As List(of IAnimal)
animalList.Add(spot)
animalList.Add(kitty)
For Each animal in animalList
Console.WriteLine(animal.Name)
animal.Speak().Listen()
Next
End Sub
What I need is a way to make an animal that first barks and then meows if the following test worked I would have the pattern I need. and
Public Sub DogCatSpeak()
dim spot = new Dog() With {.Name = "Spot" }
spot.Speak().Listen()
Dim spotBase As IAnimal = z
Dim kitty As Cat = spotBase
'Should output spot
Console.WriteLine(y.Name)
'Should output Meow
kitty.Speak().Listen()
End Sub
I'm trying to work out if I can use contravariance to allow casting Animal or IAnimal to Cat or Dog, obviously only populating the common properties.
Any thoughts or suggestions?
Aucun commentaire:
Enregistrer un commentaire