添加扩展方法 "Move" 到 generic List(Of T)":未定义 T



我想将"Move"方法作为扩展方法添加到"List(Of...)"中。

我想将其添加到通用列表中,而不是添加到特定列表中。

我的方法是这样的:

Imports System.Runtime.CompilerServices
Module ExtensionMethods
<Extension()>
Public Sub Move(ByRef uBase As List(Of T), ByVal index As Integer, ByVal newIndex As Integer)
Dim item As T = uBase.Item(index)
uBase.RemoveAt(index)
uBase.Insert(newIndex, item)
End Sub
End Module

编译器不接受"uBase As List(Of T)"行中的"T"和"将项目暗为T ="行中的"T">

这里应该使用什么?

谢谢!

首先,不要在目标参数上使用ByRef。 稍后我将对此进行扩展,因为我想跳到可以修复您的编译错误的内容。

其次,为了在List(Of T)T类型参数,它必须存在于方法定义中,因此您需要(Of T)方法。

Imports System.Runtime.CompilerServices
Module ExtensionMethods
<Extension()>
Public Sub Move(Of T)(ByVal uBase As List(Of T), ByVal index As Integer, ByVal newIndex As Integer)
'          ^^^^^^
Dim item As T = uBase.Item(index)
uBase.RemoveAt(index)
uBase.Insert(newIndex, item)
End Sub
End Module

规则:扩展方法不应**使用ByRef接受目标实例。

规则的例外:某些值 (Structure) 类型可能需要通过引用传递,以实现类似引用类型的行为(尽管值类型如果可能的话应该是不可变的)或实现更好的性能(在 C# 中,使用in关键字,以便编译器防止实例发生突变)。

以这种扩展方法为例:

Module ExtensionMethods
<Extension()>
Public Sub ConfuseMe(Of T)(ByRef list as List(Of T))
list = New List(Of T)
End Sub
End Module
Dim myList As List(Of Integer)
Dim myList2 = myList            ' A copy of the reference, but only one list object involved.
myList.Add(0)
myList.Add(1)
myList.Add(2)
myList.ConfuseMe()              ' Call an extension method that can MODIFY myList

myList不再指向同一实例。myList2指向原始实例,而myList指向在ConfuseMe中创建的新实例。 调用方没有理由期望这种情况发生。

那你为什么要做这样的事情呢? 你可能不会。 但是根据一些评论以及参考文献与参考文献之间的混淆,我可以看到它意外发生。 使用ByVal可以防止它成为难以追踪的错误。

虽然在扩展方法中是可能的,但不能使用常规实例方法执行此操作。

Class TestClass
Sub ConfuseMe()
Me = New TestClass()  ' Not possible on a Class
End Sub
EndClass
Dim x As New TestClass()
x.ConfuseMe()              ' You wouldn't expect 'x' to refer to a different instance upon return

你不能这么做。 它不允许你分配给Me(同样,值类型是例外),你不会期望x在这样的调用后指向一个新实例。

出于同样的原因,在扩展方法中执行此操作是没有意义的,其中的目的是表现得像实例方法。 由于您不需要更改调用方的变量,因此无需引用它。 只需通过接受对象实例来处理对对象的直接引用ByVal.

相关内容

最新更新