我认为答案是否定的,但我在谷歌上没有找到确凿的证据来支持这个假设。使用“vb.net“通用运算符重载”这些关键词只能得到一个结果,移除“overload”可以得到更多结果,但没有直接说明这个问题的语句。
我的想法是,如果给定一个抽象类,那么实现一个通用的运算符重载会很棒,派生类可以在这种情况下使用它,当这个运算符重载必须返回一个派生类的新副本时,每个重载的代码都是相同的。如果这有任何意义的话。
这涉及到我之前关于自定义枚举类和重载按位运算符(And,Or,Not和Xor)的问题,但是,这个特定的想法仅仅是出于好奇心而引发的。
这是我的一个自定义枚举类的基本样子: 父类EBase并不特别,只是拥有常见的Name和Value属性,以及两个共享运算符op_Equality和op_Inequality。
以下是如何使用这些工具的方法:
我需要返回一个新的
假设我有20个类似于
理论上来说,调用
我的想法是,如果给定一个抽象类,那么实现一个通用的运算符重载会很棒,派生类可以在这种情况下使用它,当这个运算符重载必须返回一个派生类的新副本时,每个重载的代码都是相同的。如果这有任何意义的话。
这涉及到我之前关于自定义枚举类和重载按位运算符(And,Or,Not和Xor)的问题,但是,这个特定的想法仅仅是出于好奇心而引发的。
这是我的一个自定义枚举类的基本样子: 父类EBase并不特别,只是拥有常见的Name和Value属性,以及两个共享运算符op_Equality和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
我必须在 EExample.Enums
定义中定义一个 Or
运算符重载,该运算符应该如何定义?
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
对象,其中包含父EExample
枚举的按位或Value
属性。 对于名称,我只需使用管道字符将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( ... )
是无效的,但我想不出能表达基本思想的正确语法。