Возможно ли создать динамический метод на C# (или, возможно, других языках .NET) в качестве метода экземпляра уже существующего типа с доступом к этой «ссылке», частным и защищенным членам?Компилировать динамический экземпляр методом дерева выражений, с помощью этого, частного и защищенного доступа?
Законный доступ к частным/защищенным членам, без ограничений видимости видимости, для меня очень важен, как это возможно при использовании DynamicMethod.
Expression.Lambda CompileToMethod (MethodBuilder) вызов выглядит очень сложным для меня, и я еще не мог найти способ, чтобы создать правильную MethodBuilder для уже существующего типа/модуль
EDIT: Теперь я создал copy Действие < DestClass, ISourceClass >, как статический/расширение, из дерева выражений. В любом случае доступ к Expression.Property (...) определяется Reflection (PropertyInfo), и я могу получить доступ к частным/защищенным членам, если они определены через Reflection. Не так хорошо, как с DynamicMethod и испускает IL, где сгенерированный метод ведет себя как член с проверками видимости (и даже немного быстрее, чем обычный код копирования C#), но деревья выражений кажутся намного лучше поддерживать.
Подобно этому, при работе с DynamicMethod и Reflection.Emit:
public static DynamicMethod GetDynamicCopyValuesMethod()
{
var dynamicMethod = new DynamicMethod(
"DynLoad",
null, // return value type (here: void)
new[] { typeof(DestClass), typeof(ISourceClass) },
// par1: instance (this), par2: method parameter
typeof(DestClass));
// class type, not Module reference, to access private properties.
// generate IL here
// ...
}
// class where to add dynamic instance method
public class DestClass
{
internal delegate void CopySourceDestValuesDelegate(ISourceClass source);
private static readonly DynamicMethod _dynLoadMethod =
DynamicMethodsBuilder.GetDynamicIlLoadMethod();
private readonly CopySourceDestValuesDelegate _copySourceValuesDynamic;
public DestClass(ISourceClass valuesSource) // constructor
{
_valuesSource = valuesSource;
_copySourceValuesDynamic =
(LoadValuesDelegate)_dynLoadMethod.CreateDelegate(
typeof(CopySourceDestValuesDelegate), this);
// important: this as first parameter!
}
public void CopyValuesFromSource()
{
copySourceValuesDynamic(_valuesSource); // call dynamic method
}
// to be copied from ISourceClass instance
public int IntValue { get; set; }
// more properties to get values from ISourceClass...
}
Этот динамический метод доступа DestClass частные/защищенные члены с полной проверки видимости.
Есть ли эквивалент при компиляции дерева выражений?
Вы не можете изменить исходный код существующего типа, если это то, что вы хотите сделать. Вы можете создать только метод расширения, однако это не будет метод экземпляра этого типа, а статический метод в другом классе. Доступ к внутренним элементам типа может быть угрозой безопасности, не так ли? – HimBromBeere
Ну, вы * * обходите пределы видимости таким образом. Вы получаете доступ к полям, к которым ранее мог обращаться только автор этого класса. Деревья выражений поддерживают частных членов, так почему бы не использовать их? 'Lambda.Compile()'. Вы можете использовать 'this', не являясь методом экземпляра. 'this' является просто скрытым параметром. – usr
@usr: приведенный выше пример IL допускает только частный/защищенный доступ в IL, если я укажу типof (DestClass) в конструкторе DynamicMethod, а не если я использую перегрузку с модулем. Существует также другая перегрузка с флагом «skipVisibility», который, согласно моему показанию, отключает проверку, в то время как мой используемый конструктор сохраняет проверку видимости, но рассматривает IL как часть DestClass. Я не знаю о внутренних компонентах, но это то, на что это похоже, и что мне теперь хотелось бы использовать деревья выражений (я также проверю, могут ли они всегда получать доступ к частным/защищенным). –