.NET 4是否允许通用运算符重载? [英] Are generic operator overloads allowed in .NET 4?
问题描述
我假设否",但我无法在Google上找到确凿的证据来支持这一假设.使用'vb.net通用运算符重载"的关键字得出的结果恰好为1,而删除'重载'给出的结果更多,但没有直接声明该问题.
I am assuming "No", but I cannot find conclusive proof on Google to back this assumption. Using keywords of 'vb.net "generic operator overload"' yields exactly 1 result, and removing 'overload' gives more, but no direct statement to the issue.
我的想法是给一个抽象类,能够实现派生类可以使用的泛型运算符重载非常好,这种情况下,当该运算符重载必须返回派生类的New副本时,但是每个重载的代码都是相同的.如果有任何意义.
My thinking is given an abstract class, it'd be great to be able to implement a generic operator overload that a derived class can use in such a case when said operator overload has to return a New copy of the derived class, yet the code for each overload is the same. If that makes any sense.
这回想起了我以前关于自定义Enum类的问题,并重载了按位运算符(And
,Or
,Not
和& Xor
),但是,这种特殊思想仅是由提示引起的好奇可以做到吗?".
This touches back to my previous questions on my custom Enum class and overloading the bitwise operators (And
, Or
, Not
, & Xor
), but, this particular thought was prompted by a mere curiosity of "Can it be done?".
以下是我的自定义枚举的基本形式:
父级EBase
没什么特别的,只托管公用的Name
和Value
属性,以及两个共享的运算符op_Equality
和op_Inequality
.
Here's what one of my custom enums basically look like:
The parent, EBase
is nothing special, just hosting common Name
and Value
properties, plus two shared operators, 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
这里是事物的使用方式:
Here's how the things are used:
Dim Foo As EExample.Enums
Foo = EExample.TwoB
Debug.Print(Foo.Name)
将打印two_boy
现在,鉴于此,如果我想执行以下操作:
Now, given that, if I want to do the following:
Dim Foo as EExample.Enums
Foo = EExample.OneA Or EExample.FiveE
我必须为EExample.Enums
定义的Or
内部定义运算符重载.这个运算符重载看起来如何?
I have to define an operator overload for Or
inside the EExample.Enums
definition. How would this operator overload look?
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
属性与管道字符连接起来,直到想到更好的地方.
I have to return a new EEXample.Enums
object containing the Bitwise-Or'ed Value
property of the parent EExample
enums. For the name, I just concatenate the Name
properties together with a pipe character until I think of something better.
假设我有20个类似于EExample
的枚举类.我必须为每个定义复制所有这些运算符重载代码,即使在IDE中,它看起来完全一样.但是,在IL中,每个重载都特定于所包含的父枚举类:
Assume I have 20 enum classes similar to EExample
. I have to duplicate all that operator overload code for each definition even though in the IDE, it looks the exact same. In IL, however, each overload is specific to the containing parent enum class:
.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
接口约束匹配,并自动提供
Then (in theory anyways), calling EExample.OneA Or EExample.FiveE
would work because the compiler would know to call the generic operator overload from EBase
, know that EExample.Enums
matches the IEnums
interface constraint, and automatically supply T
.
那或者我只是在这里游荡着一条小溪而没有桨和过度分析的东西.但这是一个有趣的想法,不是吗?什么是StackOverflow的共识?我需要解雇Spice吗?
That or I'm just swimming up a certain creek here without a paddle and over-analyzing things. But it's an interesting thought, no? What is StackOverflow's consensus? Do I need to lay off the Spice a little bit?
PS:我知道,在上一个示例中,Return New T( ... )
是无效的,但是我想不出能够表达基本思想的正确语法.
PS: I know that, in the last example, Return New T( ... )
is invalid, but I can't think of a proper syntax that would articulate the basic idea.
推荐答案
According to what I can see in the language specification, generic operators are not allowed. Section 9.8 says
至少一个操作数的类型或返回值必须是包含运算符的类型.
The type of at least one of the operands or the return value must be the type that contains the operator.
以及稍后在描述声明语法时,都无法像第9.2.1节中的方法那样考虑通用说明符.
and later when it describes the declaration syntax makes no accounting for a generic specifier as methods do in section 9.2.1.
这篇关于.NET 4是否允许通用运算符重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!