2009-10-18 5 views
11

書き込める匿名タイプのすべてのプロパティを取得する必要があります。匿名タイプの読み書きプロパティを取得する

例:

var person = new {Name = "Person's Name", Age = 25}; 
Type anonymousType = person.GetType(); 
var properties = anonymousType.GetProperties(BindingFlags.Public | BindingFlags.Instance); 

問題は、すべてのプロパティがそのCanWrite財産falseを持っているということです。これは、非匿名型の場合にtrueとして返されます。
私はまたnullを返しPropertyInfo.GetSetMethod()への呼び出しを行う試してみました。
プロパティを書き込むことができるかどうかを確認するにはどうすればよいですか?

編集: おそらく、タイプが匿名かどうかを知ることで十分でしょう。反射を使用して型が匿名であるかどうかを調べるにはどうすればよいですか?

答えて

18

C#から生成される匿名型は、常に不変です。したがって、書き込み可能なプロパティのセットは空です。 VBではオプションです:各プロパティはデフォルトでに変更可能ですが、接頭辞にKeyを付けると変更できません。 Keyを使用して宣言されたプロパティのみが等価性とハッシュコードの生成をカウントします。個人的に私はC#のアプローチが好きです。

CanWriteは、ではありません。常に、は、匿名ではないタイプのプロパティ(書き込み可能なもののみ)に対してtrueとして返されます。プロパティは、読み取り専用、書き込み専用、または読み書き可能です。例:

public class Test 
{ 
    // CanWrite will return false. CanRead will return true. 
    public int ReadOnly { get { return 10; } } 

    // CanWrite will return true. CanRead will return false. 
    public int WriteOnly { set {} } 

    // CanWrite will return true. CanRead will return true. 
    public int ReadWrite { get { return 10; } set {} } 
} 
+0

こんにちは、 「必ずしも」ではありませんか?あなたはそれについて少し詳しく説明できますか?また、私はsetメソッドも生成されることを期待していました。コンパイラは、使用されている場合にのみセッターを生成するのに十分なほどスマートですか? - ありがとう。 –

+0

また、リフレクションを使用して型が匿名であるかどうかを知ることは可能ですか? –

+0

C#で生成された匿名型のセッターを使用することはできません - 私は言うとおり、常に不変です。名前付きの型の場合、例に示すように、setterを持つかどうかは宣言に依存します。型がコンパイラによって作成されたかどうかを検出するために、別のSOの質問がどこかにあります。私はそれを見つけようとします。 –

1

匿名タイプのプロパティに割り当てることができないため、反射レポートが正しくレポートされます。

コンパイル済みのILを見ると、C#コードは通常のイニシャライザを使用しているように見えますが、コンストラクタ呼び出しとしてコンパイラによって書き直されています。クラスの外では書き込めません。

1

タイプはリフレクションを使用して匿名であれば、私はどのように見つけるのですか?

私はタイプがCompilerGenerated属性

2

.NET 2.0ランタイムが匿名型をサポートしていませんでしたようなタイプが匿名であるかどうかを判断する信頼できる方法はありませんを持っているかどうかをチェックすることができると思います。 「コンパイラ生成名」の形式に依拠することは、異なるバージョンのコンパイラで変更される可能性があるため、安全な修正ではありません。あなたは上記の文で、「どのようにプロパティを書き込むことができるかどうかを確認することができます」に関するご自身の質問に答えのようですね

:CanWriteは(真)偽とGetSetMethodではnullを返します。それらはあなたがプロパティに書き込むことができない2つの兆候です。

私たちは.NET 2.0ランタイムにしているので、あなたが本当に匿名型を識別するための任意の信頼性の高い方法を持っていないので、System.Typeを上の「IsAnonymous」プロパティがありません。

0

タイプはリフレクションを使用して匿名であれば、私はどのように見つけるのですか?

ただ、このコードを使用します。

var isAnonymousType = Attribute.IsDefined(dataType, typeof (CompilerGeneratedAttribute), false) && dataType.IsGenericType && dataType.FullName.Contains("Anonymous") && (dataType.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; 
+0

これは、あなたが 'CompilerGeneratedAttribute'をチェックするだけでよいことを示唆しています(http://stackoverflow.com/a/16349607/945456)。これらの他の小切手はすべて本当に必要ですか?編集:この[回答](http://stackoverflow.com/a/2483054/945456)と同じソースからの情報を得たようですか? –

関連する問題