如何将对象列表转换为对象在VB.net中实现的接口列表?

时间:2022-08-09 19:42:44

I am working in VB.net and have a Class, Foo, that implements an interface, IBar. I have a List of Foo's, but I need to pass a list of IBar's into a function, but I keep getting casting errors, even when I use DirectCast. My code is

我在VB.net工作并有一个Class,Foo,它实现了一个接口,IBar。我有一个Foo列表,但是我需要将一个IBar列表传递给一个函数,但即使我使用DirectCast,我仍然会遇到转换错误。我的代码是

Class Foo
    Implements IBar
End Class

Interface IBar
End Interface

Sub DoIt(ByVal l As List(Of IBar))
End Sub

Sub Main()
    Dim FooList As New List(Of Foo)
    DoIt(FooList)
End Sub

Sub Main2()
    Dim FooList As New List(Of Foo)
    DoIt(DirectCast(FooList, List(Of IBar)))
End Sub

Sub MainWorks()
    Dim FooList As New List(Of Foo)
    Dim IBarList As New List(Of IBar)

    For Each f As Foo In FooList
        IBarList.Add(f)
    Next

    DoIt(DirectCast(IBarList, List(Of IBar)))
    DoIt(IBarList)
End Sub

In both Main and Main2 I get

在主要和主要2我得到

Value of type 'System.Collections.Generic.List(Of FreezePod.Pod.Foo)' cannot be converted to 'System.Collections.Generic.List(Of FreezePod.Pod.IBar)'.

MainWorks works, but it would be really annoying and inefficient to have to do that everywhere I want to call this function.

MainWorks可以工作,但是在我想要调用此函数的任何地方都必须这样做是非常烦人和低效的。

4 个解决方案

#1


Adding this solution as another answer, this should do what you want.

添加此解决方案作为另一个答案,这应该做你想要的。

Sub DoIt(Of T As IBar)(ByVal l As List(Of T))
End Sub

Defining the sub using generics.

使用泛型定义sub。

#2


The problem is that generic types like List(Of T) don't convert to some other List(Of U) even if the cast is guaranteed to be safe. Help is coming for this in VS2010, which doesn't really help you now, of course.

问题是像List(Of T)这样的泛型类型不会转换为其他List(Of U),即使转换被保证是安全的。 VS2010的帮助即将到来,当然,这对你现在并没有什么帮助。

As I think was also suggested in the thread linked to, if DoIt can take an IEnumerable of IBar instead of a list, you could do:

正如我认为在链接的线程中也建议,如果DoIt可以采用IEnumerable的IBar而不是列表,你可以这样做:

DoIt(FooList.Cast(Of IBar))

or if you really needed a list (and could take the overhead), you could get a list:

或者如果你真的需要一个列表(并且可以承担管理费用),你可以获得一个列表:

DoIt(FooList.Cast(Of IBar).ToList)

#3


Duplicate question but for C# (same problem). There are various answers there you can translate to VB. The reason why you can't is covariance and contravariance.

重复的问题,但对于C#(同样的问题)。你可以将各种答案翻译成VB。你不能的原因是协方差和逆变。

I'm not a VB guy but my preferred C# way is to call System.Collections.Generic.List<T>.ConvertAll<Tout>(x => (Tout)x). (I don't know how that translates, if it does, to VB.)

我不是VB人,但我首选的C#方式是调用System.Collections.Generic.List .ConvertAll (x =>(Tout)x)。 (我不知道如何转换到VB。)

VB translation:

System.Collections.Generic.List(Of T).ConvertAll(Of TOut)(Function(x) CType(x, TOut))

System.Collections.Generic.List(Of T).ConvertAll(Of TOut)(Function(x)CType(x,TOut))

#4


Is a derived Base Class not an option, and have the Base Class implement the interface. That would make it work.

派生的基类不是一个选项,而是让基类实现接口。这将使它工作。

Class BaseFoo
    Implements IBar
End Class

Class Foo
    Inherits BaseFoo
End Class

Sub DoIt(ByVal l As List(Of BaseFoo))
End Sub

Something like it.

喜欢它的东西。

#1


Adding this solution as another answer, this should do what you want.

添加此解决方案作为另一个答案,这应该做你想要的。

Sub DoIt(Of T As IBar)(ByVal l As List(Of T))
End Sub

Defining the sub using generics.

使用泛型定义sub。

#2


The problem is that generic types like List(Of T) don't convert to some other List(Of U) even if the cast is guaranteed to be safe. Help is coming for this in VS2010, which doesn't really help you now, of course.

问题是像List(Of T)这样的泛型类型不会转换为其他List(Of U),即使转换被保证是安全的。 VS2010的帮助即将到来,当然,这对你现在并没有什么帮助。

As I think was also suggested in the thread linked to, if DoIt can take an IEnumerable of IBar instead of a list, you could do:

正如我认为在链接的线程中也建议,如果DoIt可以采用IEnumerable的IBar而不是列表,你可以这样做:

DoIt(FooList.Cast(Of IBar))

or if you really needed a list (and could take the overhead), you could get a list:

或者如果你真的需要一个列表(并且可以承担管理费用),你可以获得一个列表:

DoIt(FooList.Cast(Of IBar).ToList)

#3


Duplicate question but for C# (same problem). There are various answers there you can translate to VB. The reason why you can't is covariance and contravariance.

重复的问题,但对于C#(同样的问题)。你可以将各种答案翻译成VB。你不能的原因是协方差和逆变。

I'm not a VB guy but my preferred C# way is to call System.Collections.Generic.List<T>.ConvertAll<Tout>(x => (Tout)x). (I don't know how that translates, if it does, to VB.)

我不是VB人,但我首选的C#方式是调用System.Collections.Generic.List .ConvertAll (x =>(Tout)x)。 (我不知道如何转换到VB。)

VB translation:

System.Collections.Generic.List(Of T).ConvertAll(Of TOut)(Function(x) CType(x, TOut))

System.Collections.Generic.List(Of T).ConvertAll(Of TOut)(Function(x)CType(x,TOut))

#4


Is a derived Base Class not an option, and have the Base Class implement the interface. That would make it work.

派生的基类不是一个选项,而是让基类实现接口。这将使它工作。

Class BaseFoo
    Implements IBar
End Class

Class Foo
    Inherits BaseFoo
End Class

Sub DoIt(ByVal l As List(Of BaseFoo))
End Sub

Something like it.

喜欢它的东西。

相关文章