3

我想用 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"]);

FastMember_dynamic 中出现“System.ArgumentOutOfRangeException”类型的未处理异常

内部异常为空。

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

  • 1.0.0.8 - 为非公共访问器提供支持(至少我认为是这个意思)

我注意到的另一件事是,在 nuget 中,它说 1.0.0.11 是最新版本,但是下载到我的计算机上的 dllInstall-Package FastMember版本为 1.0.0.9,可能是 marc https://stackoverflow.com/users/23354 /marc-gravell看到这一点并可以修复它。:)

4

1 回答 1

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对象访问任何非公共字段/属性。

于 2014-11-07T19:17:06.883 回答