2011-11-25 22 views
10

estoy tratando de escribir un simple objeto de diccionario convertidor, como a continuación:Tipos anónimos y Obtener acceso en 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(); 
    } 
} 

Sin embargo, cuando trato de llamar a esto como:

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

Entonces se produce un error con una excepción:

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

¿Es este el modelo de seguridad de Mango que dice "No"? ¿Hay alguna manera de evitarlo? Se siente como si fuera un acceso público Obtener, por lo que parece que debería poder invocarlo.

Stuart

Respuesta

8

supongo que su método y ToSimplePropertyDictionary el uso real está en dos ensamblajes separados. Esta es la fuente de su problema porque la clase generada por el compilador que se genera a partir de una clase anónima es internal. Es por eso que obtiene la excepción MethodAccessException. Por lo tanto, debe usar el InternalsVisibleToAttribute para que funcione. Este SO question contiene más información sobre los tipos internos y la reflexión.

+0

¡Gracias! Eso suena como una buena respuesta – Stuart

+0

Tenemos un ganador, ¡gracias! – Stuart

+0

mmm, buena respuesta. Nunca hubiera pensado en esto ya que BindingFlags.Public se pasa al obtener las propiedades. Hubiera pensado que no se habrían devuelto propiedades si el tipo anónimo es interno aunque MSDN establezca que las propiedades son públicas (lo que parece extraño si la clase padre no lo está). – calum

1

Eliminar BindingFlags.GetProperty

Esto se utiliza para obtener un valor de propiedad cuando se utiliza InvokeMember, que no especifica que desea una propiedad de sólo lectura regresó.

EDIT: El problema puede ser en realidad con el propertyInfo.GetGetMethod() - Trate de usar una de las siguientes (solamente he utilizado la primera):

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