Почему индексатор в моем компоненте .NET не всегда доступен из VBScript?
У меня есть сборка .NET, к которой я получаю доступ из VBScript (классический ASP) через COM-взаимодействие. У одного класса есть индексатор (свойство a.k.a. default), который я получил, работая с VBScript, добавив следующий атрибут к индексатору:[DispId(0)]
, В большинстве случаев это работает, но не при доступе к классу как члену другого объекта.
Как мне заставить его работать со следующим синтаксисом:Parent.Member("key")
где Member имеет индексатор (аналогично доступу к свойству по умолчанию встроенногоRequest.QueryString
: Request.QueryString("key")
)?
В моем случае есть родительский классTestRequest
сQueryString
свойство, которое возвращаетIRequestDictionary
, который имеет индексатор по умолчанию.
Пример VBScript:
Dim testRequest, testQueryString
Set testRequest = Server.CreateObject("AspObjects.TestRequest")
Set testQueryString = testRequest.QueryString
testQueryString("key") = "value"
Следующая строка вызывает ошибку вместо вывода «value». Это синтаксис, который я хотел бы получить работать:
Response.Write(testRequest.QueryString("key"))
Среда выполнения Microsoft VBScript (0x800A01C2)
Неверное количество аргументов или неверное присвоение свойства: 'QueryString'
Тем не менее, следующие строкиделать работать без ошибок и выводить ожидаемое «значение» (обратите внимание, что первая строка обращается к индексатору по умолчанию для временной переменной):
Response.Write(testQueryString("key"))
Response.Write(testRequest.QueryString.Item("key"))
Ниже приведены упрощенные интерфейсы и классы в C # 2.0. Они были зарегистрированы черезRegAsm.exe /path/to/AspObjects.dll /codebase /tlb
:
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRequest {
IRequestDictionary QueryString { get; }
}
[ClassInterface(ClassInterfaceType.None)]
public class TestRequest : IRequest {
private IRequestDictionary _queryString = new RequestDictionary();
public IRequestDictionary QueryString {
get { return _queryString; }
}
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRequestDictionary : IEnumerable {
[DispId(0)]
object this[object key] {
[DispId(0)] get;
[DispId(0)] set;
}
}
[ClassInterface(ClassInterfaceType.None)]
public class RequestDictionary : IRequestDictionary {
private Hashtable _dictionary = new Hashtable();
public object this[object key] {
get { return _dictionary[key]; }
set { _dictionary[key] = value; }
}
}
Я пытался исследовать и экспериментировать с различными вариантами, но пока не нашел решения. Любая помощь будет оценена, чтобы выяснить, почемуtestRequest.QueryString("key")
синтаксис не работает и как заставить его работать.
Примечание: это продолжение кПредоставление свойства indexer / default через COM Interop.
Обновление: вот некоторые сгенерированные IDL из библиотеки типов (используяoleview):
[
uuid(C6EDF8BC-6C8B-3AB2-92AA-BBF4D29C376E),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AspObjects.IRequest)
]
dispinterface IRequest {
properties:
methods:
[id(0x60020000), propget]
IRequestDictionary* QueryString();
};
[
uuid(8A494CF3-1D9E-35AE-AFA7-E7B200465426),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AspObjects.IRequestDictionary)
]
dispinterface IRequestDictionary {
properties:
methods:
[id(00000000), propget]
VARIANT Item([in] VARIANT key);
[id(00000000), propputref]
void Item(
[in] VARIANT key,
[in] VARIANT rhs);
};