Быстрый доступ к непубличным свойствам

Я хотел заменить средство доступа индекса отражения на 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 объект.

Другие вопросы по тегам