IDisposable:方法 'X' 具有多个具有相同签名的定义
IDisposable: Method 'X' has multiple definitions with identical signatures
场景
我编写了这些扩展方法来初始化 and/or 以 elegant/simplified 的方式处理数组的所有元素以避免代码重复:
<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()
问题
我发现的问题是编译器显示此错误:
'Public Sub InitializeAll(Of T As New)(sender() As T)' has multiple
definitions with identical signatures.
...我不太理解这个错误,因为 IDisposable
是一个接口,我试图删除类型参数的“As New”但是仍然显示相同的错误。
问题
我如何调整 InitializeAll()
方法的类型参数来避免此错误并仍然以预期的行为工作?,我的意思是一种方法接受一次性对象数组,另一种方法接受非一次性物品。
我知道我可以在一个方法中 fuse/merge 两种方法的逻辑,如下所示:
<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
但我更喜欢使用两种不同的方法,因为这样我可以在不传递一次性对象数组时避免额外检查,从而提高性能。
这里真正的问题是当一个对象有一个 Constructor 并且也是 IDisposable 时会发生什么?调用哪个方法?这就是它导致问题的原因。
泛型不能用于重载,因为编译器无法在编译时区分两种不同的类型,因此认为它们相同...
所以要么你创建一个真正的重载,比如:
'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())
你得到了一个真正的重载,但正如你所说,它可能会破坏你的逻辑,然后只用一种方法,检查对象是否实现 IDisposable
.
场景
我编写了这些扩展方法来初始化 and/or 以 elegant/simplified 的方式处理数组的所有元素以避免代码重复:
<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()
问题
我发现的问题是编译器显示此错误:
'Public Sub InitializeAll(Of T As New)(sender() As T)' has multiple definitions with identical signatures.
...我不太理解这个错误,因为 IDisposable
是一个接口,我试图删除类型参数的“As New”但是仍然显示相同的错误。
问题
我如何调整 InitializeAll()
方法的类型参数来避免此错误并仍然以预期的行为工作?,我的意思是一种方法接受一次性对象数组,另一种方法接受非一次性物品。
我知道我可以在一个方法中 fuse/merge 两种方法的逻辑,如下所示:
<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
但我更喜欢使用两种不同的方法,因为这样我可以在不传递一次性对象数组时避免额外检查,从而提高性能。
这里真正的问题是当一个对象有一个 Constructor 并且也是 IDisposable 时会发生什么?调用哪个方法?这就是它导致问题的原因。
泛型不能用于重载,因为编译器无法在编译时区分两种不同的类型,因此认为它们相同...
所以要么你创建一个真正的重载,比如:
'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())
你得到了一个真正的重载,但正如你所说,它可能会破坏你的逻辑,然后只用一种方法,检查对象是否实现 IDisposable
.