首页 > 解决方案 > 如何按类型正确地将对象从 C# 传递到 VBScript?

问题描述

如何将 C# 对象传递给 VBScript?

我想要返回的 C# 类是:

namespace GSM
{

    [Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E125E")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("GSM.ParseResult")]
    public class ParseResult
    {
        public string Status;
        public HtmlNode table;

    }
}

我在 Google 上搜索了很多网站,其中大多数建议object[]作为 C# 返回值传递。在这种情况下,VBScript 可以很好地迭代和重新组合对象类型和值。例如,返回它的函数是这样的:

public object[] Parse(string userid, string password, string startDate, string endDate)
        {
            ParseResult parseResult = new ParseResult();
            parseResult.Status="OK";   

            object o = (object)parseResult;
            object[] oa = new object[] { o };
            return oa;     
        }

和 VBScript,可以很好地使用它:

Dim o
Set o = CreateObject("1C_GSM.TestComClass")
Dim a
a = o.Parse("51597", "********", "01-03-2017", "31-03-2017")
For Each entry In a
                Wscript.Echo TypeName(entry)
                Wscript.Echo entry
                Wscript.Echo entry.Status
Next

ParseResult在这种情况下,将显示三个消息:GSM.ParseResultOK

但是当我试图将我的功能更改为

public ParseResult Parse(string userid, string password, string startDate, string endDate)
            {
                ParseResult parseResult = new ParseResult();
                parseResult.Status="OK"; 

                return parseResult;     
            }

并尝试使用代码在 VBScript 中调用它

Dim o
Set o = CreateObject("1C_GSM.TestComClass")
Dim a
a = o.Parse("51597", "********", "01-03-2017", "31-03-2017")
Wscript.Echo TypeName(a)
Wscript.Echo a
Wscript.Echo a.Status

消息将是:StringGSM.ParseResult以及有关异常的消息,代码为 800A01A8 的行Wscript.Echo a.Status

为什么 VBScript 将返回对象的类型识别为 String,如果直接返回对象,则将 no 作为我的类类型,但ParseResult如果返回值被包装为,则将类型重新转换为object[]

如何强制 VBScript 识别返回对象的类型ParseResult而不将其包装到object[]?

谢谢!

标签: c#vbscriptcom

解决方案


你会为此踢自己,但你只需要使用Set a = o.Parse(...)而不是a = o.Parse(...).

对于那些想知道为什么的人:a = o.Parse(...)是隐含的Let a = o.Parse(...)Let赋值时Set使用,赋值对象时使用。用于Let分配对象时,会将对象转换为值。我不记得这个机制了,但它可能使用了标准的 COM 技术,包括IDispatchDISPID_VALUE. 调用此转换时,.NET 框架中的某些内容要么返回 ProgID,要么返回对象的完整 .NET Namespace.ClassName。


推荐阅读