В моем классе есть группа частных методов, и мне нужно вызывать их динамически на основе входного значения. И вызывающий код, и целевые методы находятся в одном и том же экземпляре. Код выглядит так:
MethodInfo dynMethod = this.GetType().GetMethod("Draw_" + itemType);
dynMethod.Invoke(this, new object[] { methodParams });
В этом случае GetMethod()
не будут возвращаться частные методы. Что BindingFlags
мне нужно предоставить, чтобы GetMethod()
он мог найти частные методы?
c#
.net
reflection
private-methods
Джероми Ирвин
источник
источник
BindingFlags.NonPublic
не возвращаетсяprivate
метод .. :(BindingFlags.Instance
а такжеBindingFlags.NonPublic
для нестатических методов.non-static
иprivate
класс унаследован отSystem.Web.UI.Page
.. это все равно делает меня дураком .. я не нашел причину .. :(BindingFlags.FlattenHierarchy
позволит вам получить методы из родительских классов к вашему экземпляру.BindingFlags.NonPublic
не вернет никаких результатов сам по себе. Как выясняется, в сочетании с этимBindingFlags.Instance
делает свое дело .источник
internal
функциямИ если вы действительно хотите попасть в неприятности, упростите выполнение, написав метод расширения:
И использование:
источник
Microsoft недавно изменила API отражения, сделав большинство этих ответов устаревшими. Следующее должно работать на современных платформах (включая Xamarin.Forms и UWP):
Или как метод расширения:
Примечание:
Если нужный метод в суперкласс родовое должен быть явно установлен на тип суперкласса.
obj
T
Если метод асинхронный, вы можете использовать
await (Task) obj.InvokeMethod(…)
.источник
GetDeclareMethod()
что они предназначены для извлечения только публичного метода.Вы абсолютно уверены, что это не может быть сделано с помощью наследования? Отражение - это самое последнее, на что следует обратить внимание при решении проблемы, оно усложняет рефакторинг, понимание вашего кода и любой автоматический анализ.
Похоже, у вас должен быть класс DrawItem1, DrawItem2 и т. Д., Который переопределяет ваш dynMethod.
источник
Отражение, особенно в отношении частных лиц, неверно
Отражение закрытых членов нарушает принцип инкапсуляции и, таким образом, предоставляет вашему коду следующее:
Что если я все равно должен это сделать?
Бывают случаи, когда вы зависите от третьей стороны или вам нужно, чтобы какой-то API-интерфейс не был раскрыт, вам нужно подумать. Некоторые также используют его для тестирования некоторых классов, которыми они владеют, но они не хотят менять интерфейс, чтобы предоставить доступ к внутренним элементам только для тестов.
Если вы делаете это, делайте это правильно
Чтобы смягчить проблему, которую легко сломать, лучше всего обнаружить любой потенциальный сбой путем тестирования в модульных тестах, которые будут выполняться в сборке с непрерывной интеграцией или тому подобном. Конечно, это означает, что вы всегда используете одну и ту же сборку (которая содержит закрытые элементы). Если вы используете динамическую нагрузку и отражение, вам нравится играть с огнем, но вы всегда можете поймать исключение, которое может вызвать вызов.
В последних версиях .Net Framework CreateDelegate в 50 раз превосходил вызов MethodInfo:
draw
вызовы будут примерно в 50 раз быстрее, чемMethodInfo.Invoke
использованиеdraw
в качестве стандартаFunc
:Проверьте этот пост, чтобы увидеть эталонный тест по различным вызовам методов.
источник
Не могли бы вы просто иметь разные методы Draw для каждого типа, который вы хотите рисовать? Затем вызовите перегруженный метод Draw, передавая объект типа itemType для рисования.
Ваш вопрос не дает понять, действительно ли itemType относится к объектам разных типов.
источник
Я думаю , что вы можете передать его ,
BindingFlags.NonPublic
где он являетсяGetMethod
методом.источник
Вызывает любой метод, несмотря на его уровень защиты на экземпляре объекта. Наслаждайтесь!
источник
Прочтите этот (дополнительный) ответ (иногда это ответ), чтобы понять, к чему это идет и почему некоторые люди в этой теме жалуются, что «это все еще не работает»
Я написал точно такой же код, как один из ответов здесь . Но у меня все еще была проблема. Я поставил точку останова на
Выполнено но
mi == null
И так продолжалось до тех пор, пока я не перестроил все вовлеченные проекты. Я тестировал одну сборку, пока метод отражения находился в третьей сборке. Это было очень странно, но я использовал Immediate Window для обнаружения методов и обнаружил, что закрытый метод, который я пытался выполнить модульным тестом, имел старое имя (я переименовал его). Это говорит мне о том, что старая сборка или PDB все еще существует, даже если проект модульного тестирования строится - по какой-то причине проект, который он тестировал, не был построен. "перестроить" сработало
источник
BindingFlags.NonPublic
источник