我有一个名为ReDictionary
编辑:我的班级声明
Public Class ReDictionary(Of TKey, TValue)
Inherits Dictionary(Of TKey, TValue)
为我的词典目的提供了一些小的增强功能。
' Wraps TryGetValue
Public Function ValueOr(key, OnNoValue)
dim TossBool = Me.TryGetValue(key, TossObj)
If TossBool Then
Return TossObj
Else
Return OnNoValue
End If
End Function
我正在尝试编写一个.Clone()
方法(浅层)作为课程的一部分。
我尝试过使用TopLevelDictionary.clone(src,dest)
语法的函数和使用TopLevelDict("Entry").Clone(src)
语法的 sub
Public Sub Clone(srcKey As TKey, destKey As TValue) As ReDictionary(Of object, object)
Dim newbook As New ReDictionary(Of Object, Object)
For Each kvp As KeyValuePair(Of Object, Object) In Me(srcKey)
newbook(kvp.Key) = kvp.Value.ToString()
Next
Me(destKey) = newbook
End Sub
这几乎是一个准代码。我可能尝试了TKey/TValue
,Object/Object
的每个组合,甚至是我想要克隆的两个字典的String/String
的具体情况。我也尝试过不指定参数/返回类型
我通常得到的错误是Cannot Convert ReDictionary(...) to ReDictionary(...)
,例如当函数临时ReDictionary为(Object, Object)
且源ReDictionary为(String, String)
时。
我想避免制作我的公共字典(Object, Object)
,因为它在内存上似乎很浪费。
我的两个词典填充在表单加载的相同函数中。一个是公共的,另一个是函数的本地,但是传递值(通过语言选择的描述)全局字典。
我已经意识到我可以很容易地编写一个克隆函数(不是ReDictionary
的一部分,它使用Dict(NewEntry) = CloneEntry(Dict("Entry")
之类的语法。之前我曾经尝试克隆对象之前有类似的东西。公共字典。
Private Function CloneObj(key) As ReDictionary(Of String, String)
Dim inObj = New ReDictionary(Of String, String)
For Each kvp As KeyValuePair(Of String, String) In pLib(key)
inObj(kvp.Key) = pLib(key)(kvp.Key)
Next
Return inObj
End Function
虽然我尝试放松对象类型时可能会遇到冲突。
Dictionary(String) of Dictionaries(String) of Strings
,Dictionary(String) of cTranslations(class) with String properties
。此时,有两个功能可以做到,但如果可能,我会更加坚定。
更新:这是我目前正在尝试使用的版本
Public Class ReDictionary(Of TKey, TValue)
Inherits Dictionary(Of TKey, TValue)
Public Function Clone(srcKey As Object) As ReDictionary(Of TKey, TValue)
Dim inObj As New ReDictionary(Of TKey, TValue)
For Each kvp As KeyValuePair(Of TKey, TValue) In Me
inObj(kvp.Key) = kvp.Value
Next
Return inObj
End Function
End Class
这是该语法的示例用法。
Dim Films As New ReDictionary(Of String, ReDictionary(Of String, String)
Films("Edge of Tomorrow") = New ReDictionary(Of String, String)
Films("Edge of Tomorrow")("Description") = "Tom Crues goes to war on Groundhog's Day"
Films("Live, Die, Repeat") = Films.Clone("Edge of Tomorrow")
Films("Birdman") = New ReDictionary(Of String, String)
Films("Birdman")("Description") = "Michael Keyton, who played a superhero 20 years ago, plays an actor who also did"
Films("The Unexpected Virtue of Ignorance") = Films.Clone("Birdman")
我实际上更改了某些克隆项的某些属性,这就是为什么我需要克隆而不是只有一个条目是对兄弟条目的引用。
函数本身实际上并没有导致任何错误,但是当我尝试使用它时,我得到(直接从调试器复制,只是缩进以便它易于阅读):
错误很明显
Value of type 'ReDictionary(Of String, ReDictionary(Of String, String))'
cannot be converted to 'ReDictionary(Of String, String)
如果我将In Me
更改为In Me(srckey)
,我会
Expression of type TValue which is not a collection type
。
将srcKey的输入更改为TValue
或TKey
也会导致错误,同时删除srckey的输入。
答案 0 :(得分:1)
首先,我想指出你应该制作对象而不是使用字典,但我离题了。
那么,为什么它不起作用呢。
首先,让我们看一下Clone
函数
Public Class ReDictionary(Of TKey, TValue)
Inherits Dictionary(Of TKey, TValue)
Public Function Clone(srcKey As Object) As ReDictionary(Of TKey, TValue)
Dim inObj As New ReDictionary(Of TKey, TValue)
For Each kvp As KeyValuePair(Of TKey, TValue) In Me
inObj(kvp.Key) = kvp.Value
Next
Return inObj
End Function
End Class
注意永远不会使用srcKey。因此,此函数返回您正在调用它的ReDictionary
的克隆,不 ReDictionary
中包含的TopLevel(srcKey)
接下来,让我们看看你是如何使用它的。
Dim Films As New ReDictionary(Of String, ReDictionary(Of String, String)
Films("Edge of Tomorrow") = New ReDictionary(Of String, String)
Films("Edge of Tomorrow")("Description") = "Tom Crues goes to war on Groundhog's Day"
Films("Live, Die, Repeat") = Films.Clone("Edge of Tomorrow")
如上所述,Films.Clone
将返回与调用ReDictionary
相同类型的ReDictionary
,这意味着您正在尝试将ReDictionary(Of String, ReDictionary(Of String, String)
分配给Films("Live, Die, Repeat")
},类型为ReDictionary(Of String, String)
这两种显然是不同的类型,因此你无法完成这项任务。
所以需要修复的是:
Clone
方法
我建议您删除srcKey
参数并使用此方法克隆您正在调用它的对象(这就是它已经在做的事情)
用法
现在,因为Clone
将克隆您正在调用它的字典,所以您可以执行以下操作:
Dim Films As New ReDictionary(Of String, ReDictionary(Of String, String)
Films("Edge of Tomorrow") = New ReDictionary(Of String, String)
Films("Edge of Tomorrow")("Description") = "Tom Crues goes to war on Groundhog's Day"
Films("Live, Die, Repeat") = Films("Edge of Tomorrow").Clone()
答案 1 :(得分:0)
正如Joe在评论中所说的那样,扩展方法最终得到了最好的效果,但是没有看到try/catch
或if/else
之外的普遍打字方式。
我找到了Dim Args as type() = SourceDict.GetType().GetGenericArguments()
,但由于我无法将变量用于对象类型,例如Dim inObject As New Dictionary(Of Args(0), Args(1))
,因此似乎需要重复。
离开这里,以防万一
Public Module DictionaryExtensions '(Of Tkey, TValue)
<Extension()>
Public Function CloneDict(ByVal SourceDict As Object,
ByVal SourceKey As String) As IDictionary
Try
Dim inObject As New Dictionary(Of String, String)
For Each kvp As KeyValuePair(Of String, String) In SourceDict(SourceKey)
inObject(kvp.Key) = SourceDict(SourceKey)(kvp.Key)
Next
Return inObject
Catch
Dim inObject As New Dictionary(Of String, Translation)
For Each kvp As KeyValuePair(Of String, Translation) In SourceDict(SourceKey)
inObject(kvp.Key) = SourceDict(SourceKey)(kvp.Key)
Next
Return inObject
End Try
End Function
<Extension()>
Public Function ValueOr(ByVal SourceObject As Object,
ByVal Key As Object,
Optional ByVal onnovalue As Boolean = False)
Dim TossBool as Boolean = SourceObject.TryGetValue(Key, TossObj)
If TossBool Then
Return TossObj
Else
Return onnovalue
End If
End Function
<Extension()>
Public Function ValueOr(ByVal SourceObject As Object,
ByVal Key As Object,
ByVal onnovalue As Object)
Dim TossBool as Boolean = SourceObject.TryGetValue(Key, TossObj)
If TossBool Then
Return TossObj
Else
Return onnovalue
End If
End Function
End Module