Fastmember访问非公共属性

时间:2014-11-07 14:48:00

标签: c# reflection fastmember

我想用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

Innerexception为null。

根据nuget https://www.nuget.org/packages/FastMember/,应该支持访问非公共属性,因为版本1.0.0.8:

  • 1.0.0.8 - 为非公共访问者提供支持 (至少我认为这意味着什么)

我注意到的另一件事是,在nuget中它说1.0.0.11是最新版本,但是在Install-Package FastMember上下载到我的计算机的dll版本为1.0.0.9,可能是marc {{3看到这个并且可以修复它。 :)

1 个答案:

答案 0 :(得分:2)

深入研究TypeAccessor内的代码(或者更确切地说是派生的DelegateAccessor),您可以看到allowNonPublicAccessors被用作作为获取非公共财产的值getter / setter ,而不是非公共财产/字段。

这是相关的一段代码(在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对象访问任何非公共字段/属性。