加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

vb.net – .NET 4中是否允许泛型运算符重载?

发布时间:2020-12-17 07:16:56 所属栏目:百科 来源:网络整理
导读:我假设“不”,但我无法找到谷歌的确凿证据来支持这一假设.使用’vb.net’的关键字,泛型运算符重载“’只产生1个结果,删除’重载’会产生更多,但没有直接声明该问题. 我的想法是给出一个抽象类,能够实现一个泛型运算符重载是很棒的,派生类可以在这种情况下使
我假设“不”,但我无法找到谷歌的确凿证据来支持这一假设.使用’vb.net’的关键字,泛型运算符重载“’只产生1个结果,删除’重载’会产生更多,但没有直接声明该问题.

我的想法是给出一个抽象类,能够实现一个泛型运算符重载是很棒的,派生类可以在这种情况下使用,当所述运算符重载必须返回派生类的新副本时,代码对于每个重载都是一样的.如果那有意义的话.

这触及了我之前关于我的自定义Enum类的问题,并且重载了按位运算符(And,Or,Not,& Xor),但是,这个特殊的想法仅仅是出于“它可以完成吗?”的好奇心.

这是我的一个自定义枚举基本上是这样的:
父,EBase没有什么特别之处,只是托管公共名称和值属性,加上两个共享运算符,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枚举的Bitwise-Or’ed 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,True)
End Operator

然后(理论上无论如何),调用EExample.OneA或EExample.FiveE会起作用,因为编译器会知道从EBase调用泛型运算符重载,知道EExample.Enums匹配IEnums接口约束,并自动提供T.

那个或者我只是在没有划桨和过度分析的情况下在这里游泳.但这是一个有趣的想法,不是吗? StackOverflow的共识是什么?我需要稍微裁掉Spice吗?

PS:我知道,在最后一个例子中,Return New T(…)是无效的,但是我想不出能够表达基本思想的正确语法.

解决方法

根据我在 language specification中可以看到的,不允许使用通用运算符.第9.8节说

The type of at least one of the operands or the return value must be the type that contains the operator.

稍后当它描述声明语法时,不会像9.2.1节中的方法那样计算泛型说明符.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读