Это продемонстрирует, что Basic говорит о том, что VB не имеет такой же степени детализации в этом, как C #. У меня есть этот кусок кода в C #, который использует отражение для динамического вызова метода во время выполнения:
var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
Причина, по которой я это делаю, заключается в том, что GetSomeData может быть любым из нескольких методов, каждый из которых получает разные данные. Какой метод вызывать здесь, зависит от строкового параметра, передаваемого в этот объект во время выполнения, поэтому значение «GetSomeData» изменяется во время выполнения.
Подпись "GetSomeData":
public List<SomeResultSetClass> GetSomeData()
Каждый из вызванных методов возвращает некоторый объект List<T>
. Затем я отправляю объект listResult в универсальный метод с именем Export, который выглядит следующим образом:
void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class;
Здесь мы сталкиваемся с проблемой. Invoke возвращает объект типа System.Object. Конечно, List<T>
также является System.Object, но представленный интерфейс - это интерфейс System.Object, а не интерфейс IList. Если я попытаюсь выполнить метод экспорта, таким образом:
myExportObj.Export(listResult, parms.filePath, parms.fileType);
код не компилируется. Ошибка:
The type arguments for method '...Export<T>...' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Нет, спасибо !! Проблема в том, что компилятор не может найти метаданные IList, потому что он смотрит на интерфейс System.Object. Теперь вы можете создать новый List<T>
, присвоить ему (List<Whatever>) listResult
, но это в первую очередь противоречит цели динамического вызова.
Исправлено изменение var
на dynamic
:
dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
Поскольку динамический обход статической проверки типов во время компиляции, мы не получаем ошибку компиляции. Затем, когда динамический объект передается методу Export, DLR (Dynamic Language Runtime) проверяет, может ли он неявно привести объект в соответствие требованиям сигнатуры метода. Что, конечно, может.
Хорошо, вот как все работает в C #. С VB строка выглядит так:
Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing)
При Option Strict On эта строка расстраивает компилятор, как и ожидалось. С ним все нормально работает. Другими словами, в VB я должен отключить проверку типов для всего модуля, который содержит строку. Нет более тонкой детализации, чем эта.