1

参加以下课程:

Public Class DocumentNumber
    Private m_DOC_NUMBER As Integer = 0

    Public Sub New(ByVal DOC_NUMBER As Integer)
        m_DOC_NUMBER = DOC_NUMBER
    End Sub

    Public Sub New(ByVal DEPOT_CODE As String)
        Dim ParseInput As Integer = 0
        If Integer.TryParse(DEPOT_CODE, ParseInput) = False Then
            m_DOC_NUMBER = 0
        Else
            m_DOC_NUMBER = ParseInput
        End If
    End Sub

    ''' <summary>
    ''' Returns the DOC_NUMBER as a zero-padded number, eg: 0000028374
    ''' </summary>
    Public Overrides Function ToString() As String
        Return Right("0000000000" & m_DOC_NUMBER.ToString(), 10)
    End Function

    ''' <summary>
    ''' Returns the DOC_NUMBER as an integer, use .ToString() zero-padded version.
    ''' </summary>
    Public Function ToInteger() As Integer
        Return m_DOC_NUMBER
    End Function

    ''' <summary>
    ''' Ensure that the DOC_NUMBER object has an implicit convert if assigned to an integer / string
    ''' </summary>
    Public Shared Widening Operator CType(ByVal d As DocumentNumber) As Integer
        Return d.ToInteger()
    End Operator

    Public Shared Widening Operator CType(ByVal d As DocumentNumber) As String
        Return d.ToString()
    End Operator

End Class

此类允许我从字符串或整数声明 DocID:

Dim DocumentID As New DOC_NUMBER("00123")
Dim DocumentID As New DOC_NUMBER(123)

这些可以通过调用ToInteger()&以任何一种格式检索ToString()

Dim NewDocumentID as Integer = DocumentID.ToInteger()
Dim NewDocumentID as String = DocumentID.ToString()

注意两个Widening Operator's - 它们也允许隐式转换含义.ToInteger(),并且.ToString()在将此类的实例分配给整数或字符串时可以省略,例如:

Dim NewDocumentID as Integer = DocumentID
Dim NewDocumentID as String = DocumentID

至今; 这一切都很好,我的下一个挑战是在分配给SqlParameter()对象时添加隐式转换。

如您所知,如果您将对象分配给 new SqlParameter(),则可以省略数据类型,并且SqlParameter()对象会自动计算出来 - 但是,如果我用我的对象尝试这个,它显然会失败:

m_db_QueryParams.Add(New SqlParameter("@DOC_NUMBER", OrderNumber))

这会产生以下错误(这是可以理解的!):

不存在从对象类型 DocumentNumber 到已知托管提供程序本机类型的映射。

我的问题:是否可以将 a 添加Widening Operator到我的类中,.ToString()当分配给SqlParameter()未提供数据类型的 a 时将返回它的方法(如下所示):

m_db_QueryParams.Add(New SqlParameter("@DOC_NUMBER", OrderNumber)) 'Convert as a string for the SqlParameter

我已将此问题标记为 VB 和 c# 作为任何一种语言的解决方案都是合适的。

4

1 回答 1

1

这里的问题是SqlParameter构造函数采用 type 的参数Object

Object由于在添加值时不会调用从扩展运算符继承的所有类。

这是因为您的类型DocumentNumber值已经是Object不需要转换的类型String

我认为你最好的选择是创建一些代码模式。您可以在 SqlParameterCollection 上创建一个扩展方法,例如:

Module SqlParameterExtensions

  <Extension()>
  Public Sub MyAddWithValue(coll As SqlParameterCollection, paramName As String, paramValue As Object)
    If (TypeOf paramValue Is DocumentNumber) Then
        coll.AddWithValue(paramName, paramValue.ToString())
    Else
        coll.AddWithValue(paramName, paramValue)
    End If
  End Sub
End Module

并称它为

Module Module1

    Sub Main()
        Dim com As New SqlCommand
        Dim docNo As New DocumentNumber
        com.Parameters.MyAddWithValue("@DOC_NO", docNo)
    End Sub

End Module

或者您可以为 SqlParameters 创建一个“工厂”方法;

Public Shared Function CreateParameter(name As String, value As Object) As SqlParameter
    If (TypeOf value Is DocumentNumber) Then
        value = value.ToString()
    End If

    Return New SqlParameter(name, value)
End Function
于 2013-08-30T11:49:19.087 回答