我需要获取可以写入的匿名类型的所有属性。
例如:
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
如何检查属性是否可以写入?
修改 也许知道一个类型是否是匿名的就足够了。如何使用反射确定某个类型是匿名的?
答案 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;