Можно ли создать динамический метод на С# (или, возможно, на других языках .NET) как метод экземпляра уже существующего типа с доступом к ссылке «эта», закрытым и защищенным членам?
Для меня очень важен законный доступ к закрытым/защищенным членам без обхода ограничений видимости, поскольку это возможно с DynamicMethod.
Вызов Expression.Lambda CompileToMethod(MethodBuilder) выглядит для меня очень сложным, и я еще не смог найти способ создать правильный MethodBuilder для уже существующего типа/модуля.
EDIT: теперь я создал копию Action‹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 с полной проверкой видимости.
Есть ли эквивалент при компиляции дерева выражений?
lambda.Compile()
. Вы можете использоватьthis
, не будучи методом экземпляра.this
- это просто скрытый параметр. - person usr   schedule 29.08.2016[Source(typeof(ISourceClass), "SourceIntValue")]
. На данный момент он анализирует атрибуты, а затем копирует значения путем отражения при каждой операции копирования. Производительность принесена в жертву удобству. Этого было достаточно в течение долгого времени, но теперь огромная потеря производительности становится проблемой. - person Erik Hart   schedule 29.08.2016ISourceClass
? - person Serge Semenov   schedule 29.08.2016