Drawing.Rectangle 的写作扩展
Writing extension for Drawing.Rectangle
Drawing.Rectangle 有方法
Dim r As Drawing.Rectangle = Drawing.Rectangle.FromLTRB(...)
我想写一个类似于那个函数的扩展方法。扩展方法将创建一个包含所有给定点的矩形。
我写过这样的方法,但是"Rectangle"没注意到有这个新方法
当我尝试访问该方法时,Intellisense 找不到它。
我已经在这样的模块中声明了扩展:
<Extension()>
Public Function FromPoints(ByVal points As List(Of Drawing.Point)) As Drawing.Rectangle
Dim leastX As Integer = 0
Dim maxX As Integer = 0
Dim leastY As Integer = 0
Dim maxY As Integer = 0
Dim bDone As Boolean = False
For Each p As Point In points
If Not bDone Then
bDone = True
leastX = p.X
maxX = p.X
leastY = p.Y
maxY = p.Y
Else
If p.X < leastX Then
leastX = p.X
End If
If p.X > maxX Then
maxX = p.X
End If
If p.Y < leastY Then
leastY = p.Y
End If
If p.Y > maxY Then
maxY = p.Y
End If
End If
Next
Return Drawing.Rectangle.FromLTRB(leastX, leastY, maxX, maxY)
End Function
我是否遗漏了任何让它发挥作用的东西?
您引用的 FromLTRB
方法是 Shared
,即它是 Rectangle
类型的成员,但不是 Rectangle
实例的成员。请注意,您在 Rectangle
上调用它,而不是在 A Rectangle
.
上调用它
扩展方法只能作为实例成员使用。您不能编写在 Rectangle
类型上调用的扩展方法,而只能编写在 Rectangle
实例上调用的扩展方法。您调用它的实例实际上由第一个参数表示。您的扩展方法必须如下所示:
Imports System.Runtime.CompilerServices
Public Module RectangleExtensions
<Extension>
Public Function FromPoints(source As Rectangle, points As List(Of Point)) As Rectangle
'...
End Function
End Module
然后你必须这样称呼它:
Dim rect As Rectangle
Dim points As New List(Of Point)
'...
Dim newRect = rect.FromPoints(points)
这并不完全理想,因为您必须有一个 Rectangle
开始,但没有办法解决这个问题,因为扩展方法需要调用被扩展类型的实例。
顺便说一下,我倾向于这样写那个方法:
Imports System.Runtime.CompilerServices
Public Module RectangleExtensions
<Extension>
Public Function FromPoints(source As Rectangle, points As IEnumerable(Of Point)) As Rectangle
Dim pointArray = points.ToArray()
Dim allX = pointArray.Select(Function(p) p.X).ToArray()
Dim allY = pointArray.Select(Function(p) p.Y).ToArray()
Return Rectangle.FromLTRB(allX.Min(),
allY.Min(),
allX.Max(),
allY.Max())
End Function
End Module
使用IEnumerable(Of Point)
使方法更灵活,使用LINQ使方法更简洁。 LINQ 实际上会使性能变差,但您必须有一个非常大的 Points
列表才能产生明显的差异。
编辑:
我应该明确指出,扩展方法需要一个实例,而这种情况在调用该方法之前不需要实例,这意味着您不应在这种情况下使用扩展方法。只需编写一个方法,获取 Points
和 returns 一个 Rectangle
的列表并将其放在适当的位置:
Public Function RectangleFromPoints(points As IEnumerable(Of Point)) As Rectangle
Dim pointArray = points.ToArray()
Dim allX = pointArray.Select(Function(p) p.X).ToArray()
Dim allY = pointArray.Select(Function(p) p.Y).ToArray()
Return Rectangle.FromLTRB(allX.Min(),
allY.Min(),
allX.Max(),
allY.Max())
End Function
Drawing.Rectangle 有方法
Dim r As Drawing.Rectangle = Drawing.Rectangle.FromLTRB(...)
我想写一个类似于那个函数的扩展方法。扩展方法将创建一个包含所有给定点的矩形。
我写过这样的方法,但是"Rectangle"没注意到有这个新方法
当我尝试访问该方法时,Intellisense 找不到它。
我已经在这样的模块中声明了扩展:
<Extension()>
Public Function FromPoints(ByVal points As List(Of Drawing.Point)) As Drawing.Rectangle
Dim leastX As Integer = 0
Dim maxX As Integer = 0
Dim leastY As Integer = 0
Dim maxY As Integer = 0
Dim bDone As Boolean = False
For Each p As Point In points
If Not bDone Then
bDone = True
leastX = p.X
maxX = p.X
leastY = p.Y
maxY = p.Y
Else
If p.X < leastX Then
leastX = p.X
End If
If p.X > maxX Then
maxX = p.X
End If
If p.Y < leastY Then
leastY = p.Y
End If
If p.Y > maxY Then
maxY = p.Y
End If
End If
Next
Return Drawing.Rectangle.FromLTRB(leastX, leastY, maxX, maxY)
End Function
我是否遗漏了任何让它发挥作用的东西?
您引用的 FromLTRB
方法是 Shared
,即它是 Rectangle
类型的成员,但不是 Rectangle
实例的成员。请注意,您在 Rectangle
上调用它,而不是在 A Rectangle
.
扩展方法只能作为实例成员使用。您不能编写在 Rectangle
类型上调用的扩展方法,而只能编写在 Rectangle
实例上调用的扩展方法。您调用它的实例实际上由第一个参数表示。您的扩展方法必须如下所示:
Imports System.Runtime.CompilerServices
Public Module RectangleExtensions
<Extension>
Public Function FromPoints(source As Rectangle, points As List(Of Point)) As Rectangle
'...
End Function
End Module
然后你必须这样称呼它:
Dim rect As Rectangle
Dim points As New List(Of Point)
'...
Dim newRect = rect.FromPoints(points)
这并不完全理想,因为您必须有一个 Rectangle
开始,但没有办法解决这个问题,因为扩展方法需要调用被扩展类型的实例。
顺便说一下,我倾向于这样写那个方法:
Imports System.Runtime.CompilerServices
Public Module RectangleExtensions
<Extension>
Public Function FromPoints(source As Rectangle, points As IEnumerable(Of Point)) As Rectangle
Dim pointArray = points.ToArray()
Dim allX = pointArray.Select(Function(p) p.X).ToArray()
Dim allY = pointArray.Select(Function(p) p.Y).ToArray()
Return Rectangle.FromLTRB(allX.Min(),
allY.Min(),
allX.Max(),
allY.Max())
End Function
End Module
使用IEnumerable(Of Point)
使方法更灵活,使用LINQ使方法更简洁。 LINQ 实际上会使性能变差,但您必须有一个非常大的 Points
列表才能产生明显的差异。
编辑:
我应该明确指出,扩展方法需要一个实例,而这种情况在调用该方法之前不需要实例,这意味着您不应在这种情况下使用扩展方法。只需编写一个方法,获取 Points
和 returns 一个 Rectangle
的列表并将其放在适当的位置:
Public Function RectangleFromPoints(points As IEnumerable(Of Point)) As Rectangle
Dim pointArray = points.ToArray()
Dim allX = pointArray.Select(Function(p) p.X).ToArray()
Dim allY = pointArray.Select(Function(p) p.Y).ToArray()
Return Rectangle.FromLTRB(allX.Min(),
allY.Min(),
allX.Max(),
allY.Max())
End Function