Как поддерживать контекстные неявные преобразования пользовательских объектов в Visual Basic .NET? - PullRequest
0 голосов
/ 03 января 2019

Я хочу использовать именованные коды ошибок в моем приложении.Это должно гарантировать, что каждый разработчик не будет путать коды ошибок только с цифрами с другими кодами, а также сократит время, необходимое разработчику, чтобы понять, что должен представлять код ошибки.

Сравните этот пример:

Function New() As Integer
    Return 0
End Function

в этом примере:

Function New() As Integer
    Return ErrorCodes.ERROR_SUCCESS
End Function

Конечно, я мог бы позволить разработчикам написать следующее:

Function New() As Integer
    Return 0 ' ERROR_SUCCESS
End Function

Однако приведенный выше код вызывает ошибку, когдаразработчик обновляет фактический код возврата, но забывает о комментарии.Некоторые разработчики смотрят на фактический код возврата, а некоторые на комментарий.Я хочу смягчить эту путаницу.

Я подхожу к следующему классу (выдержка):

Public Class ErrorCodes
    Private msName As String = Nothing
    Private miValue As Integer = 0

    Public Shared ReadOnly ERROR_SUCCESS As ErrorCodes = New ErrorCodes("ERROR_SUCCESS", 0)

    Private Sub New(ByVal psName As String, ByVal piValue As Integer)
        msName = psName
        miValue = piValue
    End Sub

    Public ReadOnly Property [Name] As String
        Get
            Return msName
        End Get
    End Property

    Public ReadOnly Property [Value] As Integer
        Get
            Return miValue
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return String.Format("[{0}]{1}", msName, miValue)
    End Function
End Class

Теперь я хочу использовать этот класс ErrorCodes, как в следующем примере:

Function New() As Integer
    Return ErrorCodes.ERROR_SUCCESS
End Function

Как и ожидалось, я выдам исключение (преобразование типа), поскольку возвращаемое мной фактическое значение является экземпляром класса ErrorCodes вместо универсального типа данных Integer.

Как вы можете видеть с помощью функции ToString(), я позволил классу автоматически / неявно преобразовать экземпляр объекта в общий тип данных String, когда экземпляр класса назначается типизированной переменной String.

Есть ли способ сделать то же самое с универсальным типом данных Integer, как я делал с ToString()?

Я использую .NET Framework 4.0, что касается соображений совместимостис Windows XP SP3.

Еще один способ сказать, что я хочу:

Dim stringVariable As String = ErrorCodes.ERROR_SUCCESS ' should be "[0]ERROR_SUCCESS".
Dim integerVariable As Integer = ErrorCodes.ERROR_SUCCESS ' should be 0.

Я не хочу запускать неявное преобразование предупреждений / ошибок или принудительно вызыватьразработчик должен явно указать тип.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Да, вы можете сделать это с использованием операторов преобразования.Вот код:

Public Class Form1
  Public Class ErrorCodes
    Private msName As String = Nothing
    Private miValue As Integer = 0

    Public Shared Widening Operator CType(ByVal ec As ErrorCodes) As String
        Return ec.ToString
    End Operator

    Public Shared Narrowing Operator CType(ByVal ec As ErrorCodes) As Integer
        Return ec.Value
    End Operator

    Public Shared ReadOnly ERROR_SUCCESS As ErrorCodes = New ErrorCodes("ERROR_SUCCESS", 0)
    Public Shared ReadOnly ERROR_FAILED As ErrorCodes = New ErrorCodes("ERROR_FAILED", 1)

    Private Sub New(ByVal psName As String, ByVal piValue As Integer)
        msName = psName
        miValue = piValue
    End Sub

    Public ReadOnly Property [Name] As String
        Get
            Return msName
        End Get
    End Property

    Public ReadOnly Property [Value] As Integer
        Get
            Return miValue
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return String.Format("[{0}]{1}", msName, miValue)
    End Function
  End Class

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim em As String = ErrorCodes.ERROR_SUCCESS
    Dim ev As Integer = ErrorCodes.ERROR_SUCCESS
    Dim mm As String = String.Format("String: {0}, Value: {1}", em, ev)

    MsgBox(mm)
  End Sub
End Class

Подробнее здесь

Надеюсь, это поможет.

0 голосов
/ 03 января 2019

Это, как указал jmcilhinney, использует Enums и атрибут Description.

Вот класс

'requires
'  Imports System.Reflection
'  Imports System.ComponentModel
Public Class ErrorCodes
    Public Enum ErrCode 'these are the error codes
        'note that the codes should be unique
        <Description("Success")> ERROR_SUCCESS = 0
        <Description("Error A")> ERROR_A = 1
    End Enum

    Public Class InfoForErrCode
        Public TheDescription As String
        Public TheValue As Integer
        Public AsString As String
    End Class

    Public Shared Function Info(TheError As ErrCode) As InfoForErrCode
        Dim rv As New InfoForErrCode
        rv.TheDescription = GetDescription(TheError)
        rv.TheValue = TheError
        rv.AsString = TheError.ToString
        Return rv
    End Function

    Private Shared Function GetDescription(TheError As ErrCode) As String
        Dim rv As String = ""
        Dim fi As FieldInfo = TheError.GetType().GetField(TheError.ToString())

        Dim attr() As DescriptionAttribute
        attr = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute),
                                                 False), DescriptionAttribute())

        If attr.Length > 0 Then
            rv = attr(0).Description
        Else
            rv = TheError.ToString()
        End If
        Return rv
    End Function
End Class

А вот как это можно использовать

    Dim foo As ErrorCodes.ErrCode = ErrorCodes.ErrCode.ERROR_SUCCESS
    Dim inf As ErrorCodes.InfoForErrCode = ErrorCodes.Info(foo)
    Stop 'examine inf
    foo = ErrorCodes.ErrCode.ERROR_A
    inf = ErrorCodes.Info(foo)
    Stop 'examine inf
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...