Позднее связывание C# для параметризованного свойства

Я пытаюсь использовать позднее связывание для подключения к API-интерфейсу автоматизации COM, предоставляемому программой Amibroker, используя проект C# WinForms. До сих пор мне удавалось подключиться ко всему в API, кроме одного элемента, который, как мне кажется, является «параметризованным свойством», основанным на обширном поиске в Google.

Вот как выглядит спецификация API согласно документации (полная версия здесь: http://www.amibroker.com/guide/objects.html):

Property Filter(ByVal nType  As Integer, ByVal pszCategory As String) As Long [r/w]

Фрагмент javascript для обновления значения выглядит следующим образом:

AB = new ActiveXObject("Broker.Application");
AA = AB.Analysis;
AA.Filter( 0, "market" ) = 0;

Используя следующий код позднего связывания C#, я могу получить значение свойства, но я не могу понять, как установить значение:

object[] parameter = new object[2];
parameter[0] = Number;
parameter[1] = Type;
object filters = _analysis.GetType().InvokeMember("Filter", BindingFlags.GetProperty, null, _analysis, parameter);

До сих пор я пробовал:

  • используя BindingFlags.SetProperty, BindingFlags.SetField
  • приведение возвращаемого объекта к объекту PropertyInfo и попытка обновить значение с его помощью
  • добавление дополнительного объекта, содержащего значение, к объекту параметров
  • различные другие вещи в качестве последних усилий

Из того, что я вижу, это должно быть прямолинейно, но я нахожу позднее связывание в С# в лучшем случае громоздким. Свойство выглядит для меня как вызов метода, что меня сбивает с толку. Как можно присвоить значение методу и как для него будет выглядеть прототип кода C# с поздним связыванием?

Надеюсь, это объясняет это достаточно хорошо, но не стесняйтесь спрашивать, оставил ли я что-то неясным. Заранее благодарю за любую помощь!

Даниэль


person optim    schedule 10.05.2010    source источник
comment
@optim: вам следует показать вызов SetProperty, поскольку он, скорее всего, будет вариантом вызова, использующего это.   -  person casperOne    schedule 11.05.2010


Ответы (2)


Да, свойства в COM реализованы как методы под капотом. Имя метода должно быть "set_Filter". Я считаю, что настоящая причина, по которой у вас возникли проблемы, заключается в том, что вы следуете объявлениям VB6. Тип VB6 Long на самом деле не является long в C#, это тип int. Попытка присвоить свойству длинное значение потерпит неудачу.

Написание этого кода на VB.NET может сделать его намного проще, он полностью поддерживает доступ к методам и свойствам с поздней привязкой, используя "естественный" синтаксис, аналогичный Java. И поддерживает индексированные свойства, в отличие от C#. Напишите небольшую сборку-оболочку, на которую вы можете ссылаться в своем проекте C#. Начиная с VS2010, он также доступен в C# с новым ключевым словом dynamic.

person Hans Passant    schedule 10.05.2010
comment
Спасибо Ганс. Вы правы, проще всего было использовать VB. Я написал быстрое приложение VB для установки фильтра, а затем использовал Reflector, чтобы преобразовать его обратно в C#. То, что у меня получилось, находится в моем сообщении с ответом, которое я могу встроить в свой класс C #, поэтому мне не нужна вторая сборка DLL. Спасибо за вашу помощь! - person optim; 11.05.2010

Вот код VB, преобразованный в C#. Это не уместилось в комментарии Гансу.

object x = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("Broker.Application", ""));
NewLateBinding.LateSetComplex(NewLateBinding.LateGet(x, null, "Analysis", new object[0], null, null, null), null, "Filter", new object[] { 0, "market", 0x22 }, null, null, false, true);

Спасибо всем за вашу помощь!

person optim    schedule 11.05.2010