Filter Custom Dictionary with LINQ ToDictionary - "Unable to cast object of type 'System.Collections.Generic.Dictionary`2"
I have created a Dictionary class (MyDictionary for the example). I am currently trying to pass MyDictionary into a function, filter it into a new instance of MyDictionary and pass this new instance into another method.
When I am attempting to create the second instance from the filtered first instance of MyDictionary via Lambda Expressions and the ToDictionary Method, I am getting the following error:
Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.Int32,System.String]' to type 'MyDictionary'.
I have simplified the example and recreated it in LINQPad and am getting the same error.
Here's the simplified version of my code:
Sub Main
Dim di1 As New MyDictionary
di1(1) = "One"
di1(2) = "Two"
di1(3) = "Three"
di1(4) = "Four"
Dim di2 As MyDictionary= _
CType(di1.Where(Function(w) w.Value.Contains("T")) _
.ToDictionary(Function(tdk) tdk.Key, Function(tdv) tdv.Value), MyDictionary)
End Sub
Public Class MyDictionary
Inherits Dictionary(Of Integer, String)
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal dictionary As IDictionary(Of Integer, String))
MyBase.New(dictionary)
End Sub
End Class
Thanks in advance, -Aaron
Per Brennen's Post: I am able to do th开发者_如何学编程e following and it's fine, I was just hoping to not do it this way.
Sub Main
Dim di1 As New MyDictionary
di1(1) = "One"
di1(2) = "Two"
di1(3) = "Three"
di1(4) = "Four"
Dim di2 = _
di1.Where(Function(w) w.Value.Contains("T")) _
.ToDictionary(Function(tdk) tdk.Key, Function(tdv) tdv.Value)
Dim di3 As New MyDictionary(di2)
End Sub
Public Class MyDictionary
Inherits Dictionary(Of Integer, String)
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal dictionary As IDictionary(Of Integer, String))
MyBase.New(dictionary)
End Sub
End Class
Does anyone else have any thoughts on how I could skip the third MyDictionary instance?
What's being returned from ToDictionary is a Dictionary, not a MyDictionary. MyDictionary is a Dictionary, but not the other way around, so it doesn't make sense to cast from Dictionary to MyDictionary.
In other words, less-derived types can't automagically be converted to more-derived types.
As Brennan mentions, MyDictionary
and Dictionary(Of Integer, String)
are completely different types, even though one derives from the other.
The ToDictionary
call returns a Dictionary(Of Integer, String)
and you're then trying to cast that dictionary to a MyDictionary
.
You could create your own ToMyDictionary
extension method to workaround this:
Dim di2 As MyDictionary = _
di1.Where(Function(w) w.Value.Contains("T")) _
.ToMyDictionary(Function(tdk) tdk.Key, Function(tdv) tdv.Value)
' ...
<Extension()>
Public Shared Function ToMyDictionary(Of T)( _
ByVal source As IEnumerable(Of T), _
ByVal keySelector As Func(Of T, Integer), _
ByVal valueSelector As Func(Of T, String)) As MyDictionary
Dim result As New MyDictionary
Dim item As T
For Each item In source
result.Add(keySelector.Invoke(item), valueSelector.Invoke(item))
Next
Return result
End Function
(Apologies if the syntax isn't entirely correct: my VB is very rusty these days.)
精彩评论