Как правильно передать объект по типу из C# в VBScript?

Как передать объект С# в VBScript?

Мой класс С#, который я хочу вернуть:

namespace GSM
{

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

    }
}

Я погуглил много сайтов, и большинство из них рекомендуют передавать object[] в качестве возвращаемого значения С#. В этом случае 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.ParseResult и OK.

Но когда я пытаюсь изменить свою функцию на

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

будут сообщения: String, GSM.ParseResult и сообщение об исключении с кодом 800A01A8 для строки Wscript.Echo a.Status.

Почему VBScript распознает тип возвращаемого объекта как String, а не как тип моего класса, если объект был возвращен напрямую, но восстанавливает тип как ParseResult, если возвращаемое значение было преобразовано в object[]?

Как заставить VBScript распознавать тип возвращаемого объекта как ParseResult без переноса его в object[]?

Спасибо!


person Arthur    schedule 27.04.2018    source источник
comment
Почему бы вам не использовать ClassInterfaceType.AutoDual или ClassInterfaceType.AutoDispatch для своего класса?   -  person xxbbcc    schedule 27.04.2018
comment
Что произойдет, если вы сделаете Set a = o.Parse(...) вместо a = o.Parse(...)?   -  person Michael Gunter    schedule 27.04.2018
comment
Я пробовал их оба, но эти изменения не решили проблему...   -  person Arthur    schedule 27.04.2018
comment
Майкл Гюнтер, ты спасаешь мое время! Большое тебе спасибо! Можете ли вы сделать это как ответ на этот вопрос?   -  person Arthur    schedule 27.04.2018


Ответы (1)


Вы будете корить себя за это, но вам просто нужно использовать Set a = o.Parse(...) вместо a = o.Parse(...).

Для тех, кто задается вопросом, почему: a = o.Parse(...) неявно Let a = o.Parse(...). Let используется при присвоении значений, а Set — при присвоении объектов. При использовании Let для назначения объекта он преобразует объект в значение. Я не помню механизма, но, вероятно, он использует стандартные методы COM, включая такие вещи, как IDispatch и DISPID_VALUE. Когда это преобразование вызывается, что-то в .NET framework возвращает ProgID или полное .NET Namespace.ClassName вашего объекта.

person Michael Gunter    schedule 27.04.2018
comment
Без Set он попытается использовать значение объекта по умолчанию вместо ссылки на объект. У него его нет, кабум. Неоднозначность синтаксиса была исправлена ​​в vb.net, свойство по умолчанию всегда должно быть индексированным свойством. - person Hans Passant; 29.04.2018