我想用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:
我注意到的另一件事是,在nuget中它说1.0.0.11是最新版本,但是在Install-Package FastMember
上下载到我的计算机的dll版本为1.0.0.9,可能是marc {{3看到这个并且可以修复它。 :)
答案 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
对象访问任何非公共字段/属性。