2011-11-25 6 views
10

は、私は以下のように辞書コンバータへの単純なオブジェクトを作成しようとしています: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()"} 

マンゴーのセキュリティモデルは「いいえ」というだけですか?その周りには道がありますか?これは公共のような感じですアクセサーを取得 - それは私がそれを呼び出すことができるように感じる?

スチュアート

答えて

8

を私は推測しているあなたのToSimplePropertyDictionary方法と実際の使用は2つの別々のアセンブリにあります。これは、匿名クラスから生成されたコンパイラ生成クラスがinternalであるため、問題の原因です。そのため、MethodAccessException例外が発生します。そのためには、InternalsVisibleToAttributeを使用する必要があります。このSO questionには、内部のタイプとリフレクションに関する詳細が含まれています。

+0

ありがとうございました!それは良い答えのように聞こえます – Stuart

+0

私たちには勝者があります - ありがとう! – Stuart

+0

mmm、良い答えです。私はプロパティを取得するときにBindingFlags.Publicが渡されるので、これを考えなかったでしょう。私は、プロパティが公開されていることをMSDNが示しているにもかかわらず、匿名型が内部である場合、プロパティは返されないと考えていました(親クラスがそうでない場合は奇妙に見えます)。 – calum

1

これはInvokeMemberを使用したときに、プロパティ値を取得するために使用されBindingFlags.GetProperty

を削除し、それはあなたが読み取り専用のプロパティが戻されるように指定していません。

EDIT:問題は、実際にpropertyInfo.GetGetMethod()ある可能性があり - (私は今までに最初のものを使用している)次のいずれかを使用してみてください:

var value = propertyInfo.GetValue(input, null); 
var value = propertyInfo.GetGetMethod().Invoke(input, null); 
関連する問題