【问题标题】:Pass NULL from a VB6 window to a .NET nullable Int32将 NULL 从 VB6 窗口传递到 .NET 可为空的 Int32
【发布时间】:2014-02-22 11:01:41
【问题描述】:

我有一个调用 .NET 方法的 VB6 窗口,将其控件值的输入传递给 C# 代码。

我希望能够将 NULL 传递给 (Int32?) 的 C# 参数,但我在我的 VB6 代码中没有找到任何可以这样做的东西。

这可能吗?如果是这样,我需要从 VB6 传递什么值才能在我的 .NET 方法中获取 NULL

【问题讨论】:

  • 如果我没记错的话,Variants 在 VB6 中可以为空。如何将其编组到 .NET 我不确定.. 因为据我所知,它不是“纯空”(如果有的话)。
  • @SimonWhitehead 是的,但是如果 C# 参数是可为空的 int,我也可以传递 Nothing 或 Empty 吗?
  • 不确定.. 不过测试一下理论会很快...
  • @SimonWhitehead 是的,我试过 Nothing、Empty、vbNull (这里是一个值,不确定 VB6 是否一般都有)。到目前为止没有运气,只是抛出了一个异常
  • 您的另一个选择是为其分配一个无效值。例如,-1 如果业务规则适合。然后你可以检查它。

标签: c# vb6 interop int nullable


【解决方案1】:

你不能。事实上,您甚至无法看到 VB6 项目中的方法。在您的 .NET 程序集上运行 Tlbexp.exe 应始终产生类似于此的警告:

TlbExp:警告 TX8013117D:类型库导出器警告处理“IFoo.test(arg),ClassLibrary1”。警告:类型库导出器在签名中遇到泛型类型实例。通用代码可能无法导出到 COM。

制作者:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IFoo {
    void test(int? arg);
}

生成的类型库将没有有 test() 方法。它不能被调用。它抱怨的泛型类型是Nullable<T>,你的Int32?是它的简写符号。

长话短说,您的 C# 根本不适合从像 VB6 这样的 COM 客户端使用。您必须将参数的声明更改为 object。首先测试 null,然后强制转换为 (short),这是 VB6 的自然契合。或者使用 Convert.ToInt32() 来灵活处理客户端使用的值类型。

【讨论】:

  • 这正是我得到的错误!我想(也害怕)同样多,非常感谢 :)
  • 您必须始终提及您看到的错误消息。为大家节省了很多时间,谷歌也非常喜欢它。无论如何,谢谢。
【解决方案2】:

尝试将 Nothing 传递给参数。它充当空值。

【讨论】:

  • 不走运,当我使用 Nothing 作为输入参数时会生成编译器错误
【解决方案3】:

不确定自@HansPassant 回答以来这些年来发生了什么变化,但我能够在 VB6 中轻松使用 C# 可空对象:

C#

[ComVisible(true)]
[Guid(...)]
public class Foo
{
    private int? _arg;

    public int? Arg => _arg;

    public void Test(int? arg)
    {
        _arg = arg;
    }
}

VB6:

Dim foo As New Foo
foo.Test CLng(1234)
Debug.Print foo.Arg '1234
foo.Test Empty
Debug.Print IsEmpty(foo.Arg) 'True
foo.Test CLng(4321)
Debug.Print foo.Arg '4321

【讨论】:

    猜你喜欢
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    相关资源
    最近更新 更多