我假设“否”,但我在谷歌上找不到确凿的证据来支持这个假设。使用关键字“vb.net“通用运算符重载””仅产生 1 个结果,删除“重载”会产生更多结果,但没有直接说明该问题。
我的想法是给定一个抽象类,如果能够实现派生类可以使用的通用运算符重载,在这种情况下,当所述运算符重载必须返回派生类的新副本时,那就太好了,但代码每个过载都是相同的。如果那有意义的话。
这又回到了我之前关于自定义枚举类和重载按位运算符的问题(And
, Or
, Not
, & Xor
),但是,这种特殊的想法只是出于“这能做到吗?”的好奇心。
这是我的自定义枚举之一的基本外观:
家长,EBase
没什么特别的,只是托管常见的Name
and Value
属性,加上两个共享运算符,op_Equality
and op_Inequality
.
Friend NotInheritable Class EExample
Inherits EBase
Private Sub New()
End Sub
Friend Shared Function GetValue(ByVal Name As String) As Enums
Dim tmpOffset As Int32 = Array.IndexOf(_Names, Name)
Return If(HasContent(Name), If(tmpOffset <> -1, Values(tmpOffset), Nothing), Nothing)
End Function
' Num of Enums defined.
Friend Shared ReadOnly MaxEnums As Int32 = 5
' String literals.
Private Shared ReadOnly _Names As String() = New String() _
{"one_adam", "two_boy", "three_charles", "four_david", "five_edward"}
' Enums.
Friend Shared ReadOnly OneA As New Enums(_Names(0), 1)
Friend Shared ReadOnly TwoB As New Enums(_Names(1), 2)
Friend Shared ReadOnly ThreeC As New Enums(_Names(2), 4)
Friend Shared ReadOnly FourD As New Enums(_Names(3), 8)
Friend Shared ReadOnly FiveE As New Enums(_Names(4), 16)
' Enum Values Array.
Friend Shared ReadOnly Values As Enums() = New Enums() _
{OneA, TwoB, ThreeC, FourD, FiveE}
Friend NotInheritable Class Enums
Inherits EBase
Private Sub New()
End Sub
Friend Sub New(ByVal Name As String, ByVal Value As Int32)
MyBase.Name = Name
MyBase.Value = Value
End Sub
End Class
End Class
以下是这些东西的使用方法:
Dim Foo As EExample.Enums
Foo = EExample.TwoB
Debug.Print(Foo.Name)
将打印two_boy
现在,考虑到这一点,如果我想做以下事情:
Dim Foo as EExample.Enums
Foo = EExample.OneA Or EExample.FiveE
我必须定义一个运算符重载Or
inside the EExample.Enums
定义。这个运算符重载看起来怎么样?
Public Shared Operator Or(ByVal lhOp As Enums, ByVal rhOp As Enums) As Enums
Return New Enums(String.Concat(lhOp.Name, "|"c, rhOp.Name),
lhOp.Value Or rhOp.Value, True)
End Operator
我必须退回一个新的EEXample.Enums
包含按位或运算的对象Value
父母的财产EExample
枚举。对于名称,我只是连接Name
属性与管道字符一起,直到我想到更好的东西。
假设我有 20 个枚举类,类似于EExample
。我必须为每个定义复制所有运算符重载代码,即使在 IDE 中,它看起来完全相同。然而,在 IL 中,每个重载都是特定于包含父枚举类的:
.method public specialname static class MyAssembly.EExample/Enums
op_BitwiseOr(class MyAssembly.EExample/Enums lhOp,
class MyAssembly.EExample/Enums rhOp) cil managed
{ ... }
但!如果在中定义,通用运算符重载将解决此问题EBase
!
Friend Interface IEnums
Property Name As String
Property Value As Int32
End Interface
Public Shared Operator Or(Of T As IEnums)(ByVal lhOp As T, ByVal rhOp As T) As T
Return New T(String.Concat(lhOp.Name, "|"c, rhOp.Name),
lhOp.Value Or rhOp.Value, True)
End Operator
然后(理论上无论如何),调用EExample.OneA Or EExample.FiveE
会起作用,因为编译器知道从以下位置调用通用运算符重载EBase
, 我知道EExample.Enums
匹配IEnums
接口约束,自动供给T
.
或者我只是在没有桨的情况下在某条小溪里游泳并且过度分析事物。但这是一个有趣的想法,不是吗? StackOverflow 的共识是什么?我需要稍微减少一下香料吗?
PS:我知道,在最后一个例子中,Return New T( ... )
是无效的,但我想不出可以阐明基本思想的正确语法。