Я предполагаю «Нет», но не могу найти убедительных доказательств в Google, подтверждающих это предположение.Использование ключевых слов «vb.net« универсальная перегрузка оператора »» дает ровно 1 результат, а удаление «перегрузки» дает больше, но не дает прямого решения вопроса.
Мое мышление дано абстрактному классуБыло бы здорово иметь возможность реализовать универсальную перегрузку оператора, которую производный класс может использовать в таком случае, когда указанная перегрузка оператора должна возвращать новую копию производного класса, но код для каждой перегрузки одинаков.Если это имеет смысл.
Это возвращает нас к моим предыдущим вопросам о моем пользовательском классе Enum и перегрузке побитовых операторов (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
Я должен определить перегрузку оператора для Or
внутри 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
объект, содержащий свойство Bitwise-Or'ed Value
родительских перечислений EExample
.Что касается имени, я просто объединяю свойства Name
вместе с символом канала, пока не подумаю о чем-то лучшем.
Предположим, у меня есть 20 классов enum, похожих на 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?Нужно ли мне немного отложить Spice?
PS: Я знаю, что в последнем примере Return New T( ... )
недействителен, но я не могу придумать правильногосинтаксис, который сформулировал бы основную идею.