【问题标题】:VB.Net Access Variables in a Generic Form ObjectVB.Net 访问通用表单对象中的变量
【发布时间】:2015-04-17 13:02:51
【问题描述】:

我的公司安排我执行一项紧急项目,将我们现有的一个程序从 VB6 更新到 VB.Net。这发生在两个阶段,我个人认为第一个阶段是浪费时间,但坚持这样做,是使用 Visual Studio 中的转换过程,然后清理错误以获得编译版本。该程序的规模很大,但由于我目前没有发言权,因此我正在尝试解决数百个编译器错误。我确实意识到我正在做的不是最佳实践,而且是一种非常令人沮丧的情况/浪费时间。

基本上有多种形式,其中一种可以调用任意数量的其他形式,这由 If 语句决定。加载表单后,新表单中的变量将被分配并打开。一些变量通常被命名,而另一些则不是。所以在 VB6 代码中它看起来像这样:

Dim frm As System.Windows.Forms.Form
If x=y Then
 frm = New frm1
 frm.Variable1 = "VarA"
 frm.Variable2 = "VarB"
Else
 frm = New frm2
 frm.Variable3 = "VarC"
 frm.Variable4 = "VarD"
End If
frm.Variable5 = "VarE"

我曾尝试在 If 语句中放置一个单独的表单对象,但由于在它之外也需要它们,它并不能真正解决问题,而且由于通用项目在其他方面被大量使用,它不会在单独的作业中复制它们是不切实际的。

我希望有一个快速的解决方案

frm.Var("Variable1") = "VarA"

但我找不到任何可以在如此大量的条件下简单实现的东西。

很抱歉没有鼓励最佳实践,因为我确实意识到任何解决方案都不会是这样,但我正在寻找最快的实现,以便我可以继续重写整个程序。

【问题讨论】:

  • 这些表单不能在它们的构造函数中自己设置这些属性,或者让它们作为构造函数参数提供吗?
  • 一个辅助类,它接受一个表单引用和一个名称值对的 IDictionary,并使用反射键找到成员,然后从值中设置它们?
  • 我曾考虑过像临时表单或类这样的东西,但是对于我需要实现的大量更改和位置,这将使它成为一个如此重大的变化,我试图避免直到我可以进入重写阶段。对于范围的概念,仅针对此问题返回的错误数量就超过了 VS 限制(这是一项非常令人沮丧的任务)。

标签: vb.net vb6


【解决方案1】:

丑陋但最简单的解决方案是将行 Option Strict Off 添加到执行此类操作的任何文件的顶部。当Option Strict 关闭时,VB.NET 将执行与VB6 相同的后期绑定操作。如果在运行时发现成员名称无效,它会抛出异常,但只要成员存在并且具有预期的签名,它就会工作。在我看来,这通常是一种不好的做法,但在这种情况下,有时可以保证这样做。

附带说明一下,当您拥有Option Strict Off 时,它实际上在做什么是使用reflection 按指定名称查找成员。从技术上讲,您可以自己手动使用反射,但它需要更多代码来做同样的事情,而这正是您似乎试图避免的。

如果您不想这样做,可以使用CTypeDirectCast 将对象强制转换为特定类型。例如:

Dim frm As System.Windows.Forms.Form
If x=y Then
    frm = New frm1
    DirectCast(frm, frm1).Variable1 = "VarA"
    DirectCast(frm, frm1).Variable2 = "VarB"
Else
    frm = New frm2
    DirectCast(frm, frm2).Variable3 = "VarC"
    DirectCast(frm, frm2).Variable4 = "VarD"
End If
frm.Variable5 = "VarE"

或者你可以像这样创建一个正确类型的变量:

Dim frm As System.Windows.Forms.Form
If x=y Then
    Dim f As New frm1
    f.Variable1 = "VarA"
    f.Variable2 = "VarB"
    frm = f
Else
    Dim f As New frm2
    f.Variable3 = "VarC"
    f.Variable4 = "VarD"
    frm = f
End If
frm.Variable5 = "VarE"

【讨论】:

  • 这让我更接近一点,谢谢。它现在在 If 语句中工作,但对于在它们之外使用的任何地方,它仍然没有正确的表单分配。但这肯定给了我一些东西,谢谢。甚至没有考虑使用 DirectCast
  • 我设法通过将其设置为最初设置为 frm1 来稍微调整它以使其能够通过 If 语句,因此它仍然可以找到值并通过编译器。感谢您的帮助,史蒂文,非常感谢。
猜你喜欢
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 2020-09-01
相关资源
最近更新 更多