Быстрый доступ к непубличным свойствам
Я хотел заменить средство доступа индекса отражения на FastMember ( https://www.nuget.org/packages/FastMember/), но наткнулся на следующую проблему.
У меня есть следующие настройки:
class Program
{
static void Main(string[] args)
{
var d = new DerivedClass
{
Name = "Derived Name Property",
BaseName = "Base Name Property",
BaseInternalName = "Base Internal Name Property",
};
Console.WriteLine(d["Name"]);
Console.WriteLine(d["BaseName"]);
Console.WriteLine(d["BaseInternalName"]);
Console.ReadLine();
}
}
public abstract class BaseClass
{
public object this[string propertyName]
{
get
{
var x = GetTypeAccessor();
return x[this, propertyName];
}
set
{
var x = GetTypeAccessor();
x[this, propertyName] = value;
}
}
protected abstract TypeAccessor GetTypeAccessor();
public string BaseName { get; set; }
internal string BaseInternalName { get; set; }
}
public class DerivedClass : BaseClass
{
public string Name { get; set; }
private TypeAccessor _typeAccessor;
protected override TypeAccessor GetTypeAccessor()
{
if (_typeAccessor == null)
_typeAccessor = TypeAccessor.Create(this.GetType(), true);
return _typeAccessor;
}
}
С этим я получаю следующее исключение, на линии Console.WriteLine(d["BaseInternalName"]);
Необработанное исключение типа "System.ArgumentOutOfRangeException" произошло в FastMember_dynamic
Не исключение - ноль.
Согласно nuget https://www.nuget.org/packages/FastMember/ должна быть поддержка доступа к непубличным свойствам, начиная с версии 1.0.0.8:
- 1.0.0.8 - обеспечить поддержку закрытых средств доступа (по крайней мере, я так думаю)
Еще одна вещь, которую я заметил, это то, что в nuget говорится, что 1.0.0.11 является самой новой версией, но DLL, которая загружается на мой компьютер Install-Package FastMember
имеет версию 1.0.0.9, возможно, marc Marc Gravell видит это и может это исправить.:)
1 ответ
Копаться в коде внутри TypeAccessor
(или, точнее, производное DelegateAccessor
), вы можете видеть, что allowNonPublicAccessors
используется в качестве значения для получения / установки закрытого свойства, а не закрытого свойства / поля.
Это соответствующий кусок кода (внутри TypeAccessor.WriteMapImpl
):
PropertyInfo prop = (PropertyInfo)member;
MethodInfo accessor;
if (prop.CanRead && (accessor = (isGet ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors))) != null)
Также вы можете увидеть CreateNew
только пытается получить доступ к публичным полям / свойствам экземпляра:
PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
Поэтому вы не можете получить доступ к закрытым полям / свойствам через TypeAccessor
объект.