IDisisable:方法' X'具有相同签名的多个定义

时间:2016-03-13 13:32:54

标签: .net arrays vb.net generics extension-methods

SCENARIO

我编写了这些扩展方法,以优雅/简化的方式初始化和/或处理数组的所有元素,以避免代码重复:

<HideModuleName>
Public Module ArrayExtensions

        <Extension>
        Public Sub InitializeAll(Of T As New)(ByVal sender As T())
            For index As Integer = 0 To (sender.Length - 1)
                sender(index) = New T
            Next index
        End Sub

        <Extension>
        Public Sub InitializeAll(Of T As IDisposable)(ByVal sender As T())
            ArrayExtensions.DisposeAll(sender)
            For index As Integer = 0 To (sender.Length - 1)
                sender(index) = Activator.CreateInstance(Of T)()
            Next index
        End Sub

        <Extension>
        Public Sub DisposeAll(Of T As IDisposable)(ByVal sender As T())
            For index As Integer = 0 To (sender.Length - 1)
                If (sender(index) IsNot Nothing) Then
                    sender(index).Dispose()
                    sender(index) = Nothing
                End If
            Next index
        End Sub

End Module

目的是在这样的常见场景中使用它:

Dim myCollection As MyDisposableType() = New MyDisposableType(100) {}

myCollection.InitializeAll()
myCollection.DisposeAll()

问题

我发现的问题是编译器显示此错误:

  

&#39; Public Sub InitializeAll(Of T As New)(sender()As T)&#39;有多个   具有相同签名的定义。

...由于IDisposable是一个界面,我真的不明白这个错误,我试图删除&#34; As New &#34;类型参数但仍然显示相同的错误。

问题

我如何调整InitializeAll()方法的类型参数以避免此错误并仍然在预期的行为中工作?我的意思是一个方法接受一次性objetc数组,另一个方法接受非一次性物品。

我知道我可以在下面的单个方法中融合/合并两种方法的逻辑:

<Extension>
Public Sub InitializeAll(Of T As New)(ByVal sender As T())

    For index As Integer = 0 To (sender.Length - 1)

        If (sender(index) IsNot Nothing) Then

            If sender(index).GetType.GetInterfaces.Contains(GetType(IDisposable)) Then
                DirectCast(sender(index), IDisposable).Dispose()
                sender(index) = Nothing
            End If

        End If

        sender(index) = New T

    Next index

End Sub

但我更喜欢使用两种不同的方法,因为当我没有传递一次性对象数组时,我会获得性能,避免额外的检查。

1 个答案:

答案 0 :(得分:1)

这里真正的问题是当一个对象有一个构造函数并且也是IDisposable时会发生什么?要调用哪种方法?这就是它导致问题的原因。

通用类型不能用于重载,因为编译器无法在编译时区分两种不同的类型,因此认为它们是相同的......

所以你要么创建一个真正的Overload,比如:

'Would mean you can Dispose them, but you have to load the method with Reflection
Public Overload Sub InitializeAll(of T As New)(ByVal Sender As T(), ByVal CollectionIsDisposable As Boolean)

'So here they are not disposable...
Public Overloads Sub InitializeAll(of T As New(ByVal Sender As T())

然后你会得到一个真正的Overload,但正如你所说,它可能会破坏你的逻辑,然后只使用一种方法,并检查对象是否实现IDisposable