【发布时间】:2016-03-13 13:32:53
【问题描述】:
场景
我编写了这些扩展方法来以优雅/简化的方式初始化和/或处理数组的所有元素,以避免代码重复:
<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)' 有多个 具有相同签名的定义。
...我不太明白这个错误,因为IDisposable 是一个接口,我试图删除类型参数的“As New”但仍然显示相同的错误。
问题
我如何调整InitializeAll() 方法的类型参数以避免此错误并仍然以预期的行为工作?我的意思是一种方法接受一次性对象数组,而另一种方法接受非一次性对象.
我知道我可以将两种方法的逻辑融合/合并到一个方法中,如下所示:
<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
但我更喜欢使用两种不同的方法,因为这样可以在不传递一次性对象数组时避免额外检查,从而获得性能。
【问题讨论】:
-
如果您有第三个定义,其中
T是IDisposable并且有一个无参数构造函数(即有new)会发生什么? -
将
InitializeAll(Of T As New)重命名为CreateInitializeAll(Of T As New) -
@T.S.更改方法名称不是有效或真正的解决方案,它们具有相同的名称来应用方法重载。还是谢谢你。
-
@Wai Ha Lee 对于“构造函数”,您是指方法签名吗? (无参数方法),在这种情况下什么都不会发生,因为扩展方法应该至少声明 1 个参数......源对象。无论如何也谢谢!。
标签: .net arrays vb.net generics extension-methods