Динамически вызывать свойства по имени строки с помощью VB.NET

В настоящее время я работаю над проектом, где часть кода выглядит так:

Select Case oReader.Name
    Case "NameExample1"
        Me.Elements.NameExample1.Value = oReader.ReadString
    ....
    Case "NameExampleN"
        Me.Elements.NameExampleN.Value = oReader.ReadString
    ....
End Select

Это продолжается какое-то время. Код явно многословен и чувствуется, что его можно улучшить. Есть ли способ динамически вызывать свойство в VB.NET, чтобы можно было сделать что-то вроде этого:

Dim sReadString As String = oReader.ReadString
Me.Elements.InvokeProperty(sReadString).Value = sReadString

person Tom    schedule 27.10.2008    source источник


Ответы (3)


Другие ответили совершенно разумно, но на всякий случай, если это чувствительный к производительности фрагмент кода, вы можете захотеть скомпилировать рефлексивные вызовы в делегаты.

У меня есть запись в блоге о превращении MethodBase.Invoke в делегаты . Код написан на C#, но тот же метод можно применить и к VB.NET. Чтобы использовать это со свойствами, получите соответствующий метод установки с PropertyInfo.GetSetMethod, а затем создайте делегат, который его вызывает. У вас может быть карта от имени поля до «делегата для вызова, чтобы установить поле».

Просто повторюсь, это действительно необходимо, только если это часть кода, критическая для производительности. В противном случае вы все равно можете создать Dictionary<string, PropertyInfo>, чтобы избежать многократных вызовов GetProperty, но о шаге по преобразованию его в делегата, вероятно, не стоит беспокоиться.

person Jon Skeet    schedule 27.10.2008
comment
CallByName выглядит проще. Чем это отличается от Reflection с точки зрения производительности? - person EndangeredMassa; 28.09.2009
comment
Я считаю, что CallByName использует Reflection внутри, и я подозреваю, что применяет различные махинации, специфичные для VB, для обратной совместимости. Протестируйте его, но я очень сомневаюсь, что вы увидите, что он работает так же быстро, как делегат. Да, использование MakeDelegate сложнее, но гораздо более эффективно, чем отражение. - person Jon Skeet; 28.09.2009
comment
ваша ссылка на запись в блоге не работает - person Fredou; 19.10.2015

Не могу поверить, что другие плакаты говорили тебе использовать отражение. VB как CallByName функция, которая делает именно то, что вы хотите.

person Jonathan Allen    schedule 30.10.2008
comment
Святое дерьмо, если бы я знал об этом много лет назад. - person David Rutten; 17.01.2012
comment
Это отличный быстрый и грязный метод для простых/небольших случаев использования. Я бы не стал использовать это для чего-то сложного или там, где у вас много «работы», если только производительность не имеет значения. - person DavidScherer; 15.03.2019
comment
Если вас беспокоит производительность, вам следует использовать генерацию кода во время выполнения вместо отражения. - person Jonathan Allen; 17.03.2019

Да, CallByName — лучшее решение для вас. Вот инструкция как это сделать:

CallByName(yourClassOrObjectName,"NameExample1",CallType.Set,oReader.ReadString)

Вы можете написать «NameExample» вместо «NameExample1».
Упомяните, что третий параметр позволяет вам «получить», «позволить» этому параметру (и даже вызвать любой метод).
Таким образом, вы можете получить значение вашего параметра. используя CallType.Get.

person Jet    schedule 24.03.2013