Get read/write properties of Anonymous Type

2019-04-20 11:53发布

I need to fetch all the properties of an anonymous type which can be written to.

eg:

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

The problem is that all the properties have their CanWrite property false. This is returned as true for non anonymous types.
I have also tried making a call to PropertyInfo.GetSetMethod() which returns null.
How can I check whether the property can be written to?

Edit: Perhaps it would suffice to know if a type is anonymous or not. How do I find out if a type is anonymous using reflection?

5条回答
萌系小妹纸
2楼-- · 2019-04-20 12:32

Anonymous types generated from C# are always immutable, so the set of writable properties is empty. In VB it's optional: each property defaults to being mutable, but if you prefix it with Key it's immutable; only properties declared using Key count for equality and hash code generation. Personally I prefer C#'s approach.

CanWrite isn't always returned as true for properties in non-anonymous types - only for writable ones. Properties can be read-only, write-only, or read-write. For example:

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 {} }
}
查看更多
混吃等死
3楼-- · 2019-04-20 12:32

There is no reliable way to determine if a type is anonymous as the .NET 2.0 runtime didn't support anonymous types. Relying on the format of the "compiler generated name" is not a safe fix as this is likely to change with different versions of the compiler.

It sounds like you answered your own question regarding "How can I check whether the property can be written to" with the statements above: CanWrite is false and GetSetMethod(true) returns null. Those are two signs that you can't write to the property.

Since we're on the .NET 2.0 runtime, there is not an "IsAnonymous" property on System.Type so you don't really have any reliable method to identify an anonymous type.

查看更多
\"骚年 ilove
4楼-- · 2019-04-20 12:36

How do I find out if a type is anonymous using reflection?

I think you can check if the type has the CompilerGenerated attribute

查看更多
Luminary・发光体
5楼-- · 2019-04-20 12:42

How do I find out if a type is anonymous using reflection?

Just use this code.

var isAnonymousType = Attribute.IsDefined(dataType, typeof (CompilerGeneratedAttribute), false) && dataType.IsGenericType && dataType.FullName.Contains("Anonymous") &&  (dataType.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
查看更多
别忘想泡老子
6楼-- · 2019-04-20 12:48

Properties of anonymous types cannot be assigned to, so reflection reports correctly.

If you were to look at the compiled IL, you'll notice that though the C# code looks like it is using a normal initializer, it is rewritten by the compiler to be a constructor call, which allows the properties to be non-writable outside of the class.

查看更多
登录 后发表回答