10

I'm trying to write a simple object to Dictionary converter like below:

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();
    }
}

However, when I try to call this like:

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

Then it fails with an exception:

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

Is this just the security model on Mango saying "No"? Is there any way around it? It feels like this is a public Get accessor - so it feels like I should be able to invoke it?

Stuart

Stuart
  • 66,722
  • 7
  • 114
  • 165

2 Answers2

8

I guess that your ToSimplePropertyDictionary method and the actual usage are in two separate assemblies. This is the source of your problem because the compiler generated class which is generated from an anonymous class is internal. That is why you get the MethodAccessException exception. So you need to use the InternalsVisibleToAttribute to make it work. This SO question contains more info about internal types and reflection.

Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • mmm, good answer. I never would have thought of this as BindingFlags.Public is passed when getting the properties. I would have thought that no properties would have been returned if the anonymous type is internal even though MSDN states that the properties are public (which seems odd if the parent class isn't). – calum Nov 25 '11 at 19:54
1

Remove BindingFlags.GetProperty

This is used to get a property value when using InvokeMember, it does not specify that you want a read only property returned.

EDIT: The problem may actually be with the propertyInfo.GetGetMethod() - Try using one of the following (I have only ever used the first one):

var value = propertyInfo.GetValue(input, null);
var value = propertyInfo.GetGetMethod().Invoke(input, null); 
calum
  • 1,580
  • 10
  • 11