2014-11-07 2 views
3

Я хотел заменить свой индекс индекса отражения на FastMember (https://www.nuget.org/packages/FastMember/), но наткнулся на следующую проблему.Доступ к 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 имеет версию 1.0.0.9, может быть, Марк https://stackoverflow.com/users/23354/marc-gravell видит это и ca n исправить это. :)

ответ

2

копания в коде внутри 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.

+1

Спасибо за информацию, я изменил библиотеку, чтобы передать BindingFlags в метод TypeAccessor.Create. –

+1

Вы должны отправить запрос на перенос на @MarcGravell :) –