我创建了一个继承List(Of TKey, TValue)
的类并添加了一些函数。它的目的不是在运行时向它添加项目,而是在初始化时。我实际上想从类中删除add / delete方法(因为它当前从继承的类中公开它们)。
如果你看到TestApp
课程,你会看到,如果我在课堂上添加List(Of String, Integer)
,它就可以了。但是,在下面提供的代码中,当我尝试在类构造函数中使用Me.Add()
时;添加它不起作用。它实际上告诉我,String不能转换为TKey,并且Integer不能转换为TValue。这是不真实的!它在测试应用程序中运行良好。
有什么想法吗?这是代码。两个类,Vars类和Test应用程序。
注意:即使在类中使用覆盖Add
方法,因为Me.Add(String, Integer)
不起作用(相同的错误)
Imports System
Imports System.Collections.Generic
Imports System.Text
Public Class Vars(Of TKey, TValue)
Inherits List(Of KeyValuePair(Of TKey, TValue))
''' <summary>
''' Initializes the class and fills with Key->Value Pairs
''' </summary>
''' <remarks>
''' This does not work when adding directly from the class. When I overload
''' the Add() function, and call it with a KeyValuePair(Of String, String) in a
''' class instance it works, see below
''' </remarks>
Public Sub New()
Dim kv = New KeyValuePair(Of TKey, TValue)("This", 1)
Me.Add(kv)
End Sub
''' <summary>
''' Adds an item to the class by String, Integer
''' </summary>
''' <param name="aKey">A String containing the Key of the element to be added.</param>
''' <param name="aValue">An Integer containing the Value of the element to be added.</param>
''' <remarks>
''' This Works fine when called as in the demo shown below.
''' </remarks>
Public Overloads Sub Add(ByVal aKey As TKey, ByVal aValue As TValue)
Dim kv = New KeyValuePair(Of TKey, TValue)(aKey, aValue)
Me.Add(kv)
End Sub
''' <summary>
''' Finds a Value stored in the class based on a given Key.
''' </summary>
''' <param name="key">A String containing a Key to search for.</param>
''' <remarks>Works.</remarks>
Public Function FindByKey(ByVal key As TKey) As List(Of KeyValuePair(Of TKey, TValue))
Return Me.FindAll(Function(item As KeyValuePair(Of TKey, TValue)) (item.Key.Equals(key)))
End Function
''' <summary>
''' Finds a Key stored in the class based on a given Value.
''' </summary>
''' <param name="value">An Integer containing the Value to search for.</param>
''' <remarks>Works</remarks>
Public Function FindByValue(ByVal value As TValue) As List(Of KeyValuePair(Of TKey, TValue))
Return Me.FindAll(Function(item As KeyValuePair(Of TKey, TValue)) (item.Value.Equals(value)))
End Function
End Class
Public Class TestApp
Shared Sub Main()
Dim varTest As Vars(Of String, Integer) = New Vars(Of String, Integer)
varTest.Add("Kung", 1)
varTest.Add("Foo", 2)
For Each var In varTest
Console.WriteLine(var.Key & ":" & var.Value)
Next
'Output would be
'
' Kung:1
' Foo:2
End Sub
End Class
答案 0 :(得分:7)
这里发生了很多事情。
具体来说:您的班级是是通用的吗?就是这样
您将使用Vars(Of String, Integer)
,Vars(Of Object,
DateTime)
,Vars(Of Double, Object)
以及所有种类?如果是的话,那么
你想在这一行上发生什么:
Dim kv = New KeyValuePair(Of TKey, TValue)("This", 1)
当TKey
不 String
时,TValue
不 Integer
?该
只有你可以添加到List(Of KeyValuePair(Of TKey, TValue))
是一个KeyValuePair(Of TKey, TValue)
,而不是任何旧的
KeyValuePair
。
更一般地说:List(Of T)
is not designed to be inherited
from(这出现了很多,这只是第一个示例答案
我发现)。一定要让你的班级包含一个List(Of T)
,并将项目保留在其中,但是
而不是继承,你应该确切地决定你想要什么
您的类的公共接口 ,并且只实现它。它
可能是实施IList
或其他一些预先定义的界面为您提供您想要的合同,但不一定。
更普遍的说:当你发现自己说“我会的时候
喜欢从类中删除添加/删除方法“,这是一个
大胆暗示你不应该从该类继承。该
Liskov substitution principle(粗略地)说出任何事情
继承自类C
应该能够像C
一样对待:
如果你继承自List
,那么来电者很自然会期待
能够Add
和Delete
。如果你不想要那些方法
你的公共接口,不要从该类继承。
答案 1 :(得分:0)
在这里建立另一个答案还包括如何解决问题的建议,这是一个经典案例,应该使用组合,而不是继承。创建一个将列表包装为私有成员的类型。新类型将只包含您想要的方法和属性。它很容易实现,但有点单调乏味,因为新类型中的每个方法或属性只会调用原始方法中的相应方法。