2011-11-25 3 views
10

Sto cercando di scrivere un oggetto semplice al convertitore dizionario come di seguito:Tipi anonimi e Get accessors su 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(); 
    } 
} 

Tuttavia, quando provo a chiamare questo tipo:

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

Poi non riesce con un'eccezione:

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

Questo è solo il modello di sicurezza di Mango che dice "No"? C'è un modo per aggirarlo? Sembra che questo sia un accesso pubblico a Get - quindi è come se dovessi essere in grado di invocarlo?

Stuart

risposta

8

Credo che il metodo ToSimplePropertyDictionary e l'utilizzo effettivo è in due gruppi separati. Questa è la fonte del tuo problema perché la classe generata dal compilatore generata da una classe anonima è internal. Ecco perché ottieni l'eccezione MethodAccessException. Quindi è necessario utilizzare il InternalsVisibleToAttribute per farlo funzionare. Questo SO question contiene più informazioni sui tipi interni e sulla riflessione.

+0

Grazie! Sembra una buona risposta – Stuart

+0

Abbiamo un vincitore - grazie! – Stuart

+0

mmm, buona risposta. Non avrei mai pensato a questo come BindingFlags.Public è passato quando ottenere le proprietà. Avrei pensato che nessuna proprietà sarebbe stata restituita se il tipo anonimo fosse interno anche se MSDN afferma che le proprietà sono pubbliche (che sembra strano se la classe genitore non lo è). – calum

1

Rimuovere BindingFlags.GetProperty

Questo è usato per ottenere un valore di proprietà quando si utilizza InvokeMember, non specifica che si desidera un solo immobile lettura restituito.

EDIT: Il problema può effettivamente essere con il propertyInfo.GetGetMethod() - Prova a utilizzare uno dei seguenti (ho sempre e solo usato la prima):

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