在VB.Net过程声明中,指定多个可能类型的对象参数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在VB.Net过程声明中,指定多个可能类型的对象参数?相关的知识,希望对你有一定的参考价值。

在VB.Net中声明过程时,传递的参数是一个对象,是否可以用“Or”类型的语法指定几种可能的对象类型?

例如,我想传递一个“list”控件,以便该过程可以访问.Items集合。但是,如果我尝试概括并将参数指定为Windows.Forms.Control,则会生成错误,因为.Items不是.Control对象的成员。

我在VB语言参考中看到提到“类型列表”,这似乎几乎是我想要的,但并不完全。

以下是一些代码来演示这个问题......

Friend Sub ListFill( _
    ByRef SourceControl As Windows.Forms.WebBrowser, _
    ByRef TargetControl As Windows.Forms.Control)

    TargetControl.Items.Add(SourceControl.DocumentTitle)
    ' Error: 'Items' is not a member of 'System.Windows.Forms.Control'.

从一般意义上讲,我需要这样的语法......

Friend Sub name ( ByRef varname As { type1 Or type2 Or ... } = defaultvalue )

但就实际工作代码而言,就我而言......

Friend Sub ListFill( _
    ByRef SourceControl As Windows.Forms.WebBrowser, _
    Optional ByRef TargetControl As Windows.Forms.ListBox = Nothing, _
    Optional ByRef TargetControl As Windows.Forms.ComboBox = Nothing)

    'Error: Parameter already declared with name 'TargetControl'.

可以这样做吗?

答案

您可以检查TargetControl的控件类型,然后转换为该控件,访问它的属性。

Friend Sub ListFill( _
ByRef SourceControl As Windows.Forms.WebBrowser, _
ByRef TargetControl As Windows.Forms.Control)
    If TargetControl.GetType() Is GetType(ListBox) Then
        DirectCast(TargetControl, ListBox).Items.Add(SourceControl.DocumentTitle)

    ElseIf TargetControl.GetType() Is GetType(ComboBox) Then
        DirectCast(TargetControl, ComboBox).Items.Add(SourceControl.DocumentTitle)

    End If
End Sub

另一种解决方案是重载该方法。

Friend Sub ListFill( _
ByRef SourceControl As Windows.Forms.WebBrowser, _
ByRef TargetControl As Windows.Forms.ListBox)
    TargetControl.Items.Add(SourceControl.DocumentTitle)
End Sub

Friend Sub ListFill( _
ByRef SourceControl As Windows.Forms.WebBrowser, _
ByRef TargetControl As Windows.Forms.ComboBox)
    TargetControl.Items.Add(SourceControl.DocumentTitle)
End Sub

阅读更多:Procedure Overloading - MSDN

另一答案

如果Items集合是您唯一需要的东西

如果Items集合是您需要从这些控件中获取的唯一内容,并且您需要从中读取数据,则可以将列表传递给您的方法并使用它:

Public Sub DoSome(list As List(Of Object))
    'Use list here, for example:
    For Each item In list
        MessageBox.Show(item.ToString())
    Next
End Sub

并通过Items作为List(Of Object)

Dim list = Me.ListBox1.Items.Cast(Of Object)().ToList()
DoSome(list)

您也可以使用List(Of String)或您的物品所需的任何其他List(Of T)


如果你需要传递整个ListBox / ComboBox或者你需要操作

如果需要将整个ListBox / ComboBox对象传递给方法,或者需要传递项集合以进行操作,则使用多个重载。例如对于整个ListBox / ComboBox

Public Sub DoSome(list As ListBox)
    'Use list here, it's of type ListBox, for example
    MessageBox.Show(list.Name)
End Sub

Public Sub DoSome(combo As ComboBox)
    'Use combo here, it's of type ComboBox, for example
    MessageBox.Show(combo.Name)
End Sub

以下是用法:

DoSome(Me.ComboBox1)
DoSome(Me.ListBox1)

如果需要,可以为ListBox.ObjectCollectionComboBox.ObjectCollection做同样的事情。

另一答案

@visualvincent,谢谢。你的答案最接近我的需要。我是一个紧凑和多功能代码的奉献者,并且做得最少。有时我花了很多时间编写一小段代码。

我无法使DirectCast()工作。相反,在经过多次阅读后,我发现另一个人使用了一个与我密切相关的问题。它描述了CTypeDynamic()函数的使用,这是我拼图的最后一部分。在这里显示... 'objType' is not defined... Actually, it is, so why is this happening?

下面是我拼凑在一起的,我测试了它,它完美地工作......

Friend Sub ListboxFill(ByRef SourceControl As Windows.Forms.WebBrowser, _
                       ByRef TargetControl As Windows.Forms.Control)

    Dim typ As System.Type = TargetControl.GetType
    Select Case typ
        Case GetType(ListBox), GetType(ComboBox)
            CTypeDynamic(TargetControl, typ).Items.Add(SourceControl.DocumentTitle)
    End Select

End Sub

感谢大家的帮助..!!

以上是关于在VB.Net过程声明中,指定多个可能类型的对象参数?的主要内容,如果未能解决你的问题,请参考以下文章

VB.NET 表单变量是如何处理的

第三周 学习总结

VB.net学习笔记(二十三)再识委托

如何在不知道查询结果类型的情况下在 EF/VB.net 中运行存储过程?

VB.NET是如何使用ADO让存储过程返回数据表中的值呢?求解!

Java 泛型