获取匿名类型的读/写属性

时间:2009-10-18 17:09:55

标签: c# reflection anonymous-types

我需要获取可以写入的匿名类型的所有属性。

例如:

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

问题是所有属性都有CanWrite属性false。对于非匿名类型,这将返回true 我还尝试拨打PropertyInfo.GetSetMethod()来回复null 如何检查属性是否可以写入?

修改 也许知道一个类型是否是匿名的就足够了。如何使用反射确定某个类型是匿名的?

5 个答案:

答案 0 :(得分: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 {} }
}

答案 1 :(得分:2)

由于.NET 2.0运行时不支持匿名类型,因此没有可靠的方法来确定类型是否是匿名的。依赖于“编译器生成的名称”的格式不是一个安全的修复,因为这可能会随着编译器的不同版本而改变。

听起来你回答了自己的问题,“我如何检查属性是否可以写入”上面的语句:CanWrite为false,GetSetMethod(true)返回null。这是两个你不能写信给房产的标志。

由于我们使用的是.NET 2.0运行时,System.Type上没有“IsAnonymous”属性,因此您没有任何可靠的方法来识别匿名类型。

答案 2 :(得分:1)

无法分配匿名类型的属性,因此反射报告正确。

如果您要查看已编译的IL,您会注意到虽然C#代码看起来像是使用普通的初始化程序,但它会被编译器重写为构造函数调用,这允许属性为非在课堂外可写。

答案 3 :(得分:1)

  

如何使用反射确定某个类型是匿名的?

我认为您可以检查该类型是否具有CompilerGenerated属性

答案 4 :(得分:0)

  

如何使用反射确定某个类型是匿名的?

只需使用此代码。

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