Анонимные типы и Get accessors на WP7.1?

Я пытаюсь написать простой объект для конвертера словаря, как показано ниже:

public static class SimplePropertyDictionaryExtensionMethods
{
    public static IDictionary<string,string> ToSimplePropertyDictionary(this object input)
    {
        if (input == null)
            return new Dictionary<string, string>();

        var propertyInfos = from property in input.GetType()
                                .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.GetProperty)
                            where property.CanRead
                            select property;

        return propertyInfos.ToDictionary(x => x.Name, x => input.GetPropertyValueAsString(x));
    }

    public static string GetPropertyValueAsString(this object input, PropertyInfo propertyInfo)
    {
        var value = propertyInfo.GetGetMethod().Invoke(input, new object[] {});
        if (value == null)
            return string.Empty ;

        return value.ToString();
    }
}

Однако, когда я пытаюсь называть это так:

var test = (new { Foo="12", Bar=15 }).ToSimplePropertyDictionary();

Затем он выходит из строя с исключением:

[System.MethodAccessException]: {"Attempt to access the method failed: .<>f__AnonymousType0`1.get_Foo()"}

Это просто модель безопасности на манго, говорящая "Нет"? Есть ли способ обойти это? Похоже, что это публичный доступ к Access, поэтому мне кажется, что я должен его вызывать?

Стюарт

Ответ 1

Я предполагаю, что ваш метод ToSimplePropertyDictionary и фактическое использование находятся в двух отдельных сборках. Это является источником вашей проблемы, потому что генерируемый компилятором класс, созданный из анонимного класса, internal. Вот почему вы получаете исключение MethodAccessException. Поэтому вам нужно использовать InternalsVisibleToAttribute, чтобы он работал. Этот вопрос fooobar.com/questions/212248/... содержит больше информации о внутренних типах и отражении.

Ответ 2

Удалить BindingFlags.GetProperty

Это используется для получения значения свойства при использовании InvokeMember, оно не указывает, что вы хотите вернуть свойство только для чтения.

РЕДАКТИРОВАТЬ: Проблема может быть в самом деле с propertyInfo.GetGetMethod() - Попробуйте использовать одно из следующих (я только когда-либо использовал первый):

var value = propertyInfo.GetValue(input, null);
var value = propertyInfo.GetGetMethod().Invoke(input, null);