在新的.NET Framework 4.5中玩反射时,我遇到了一个奇怪的行为,我觉得这是出乎意料的。命名空间System.Reflection为利用Type对象提供了一些新的扩展方法。其中两个是GetRuntimeProperty(字符串名称(和GetRuntimeProperties((。
现在假设您有一个具有内部属性的简单对象。
public class ObjectBase
{
protected int Id { get; set; }
public string Name { get; set; }
}
现在你试图利用这种类型。
var properties = typeof(ObjectBase).GetRuntimeProperties();
// properties.Count = 2
var idProperty = typeof(ObjectBase).GetRuntimeProperty("Id");
var nameProperty = typeof(ObjectBase).GetRuntimeProperty("Name");
// idProperty = null
// nameProperty = System.String Name
正如预期的那样,properties
对象拥有Id和Name属性定义的两个属性定义,而nameProperty则拥有Name属性定义。不希望idProperty
对象为null。。。
来自.NET Framework,我想这是微软架构师想要的,但我必须说,这似乎不是你真正期望发生的事情。我确实认为这种类似的方法应该表现相同,但GetRuntimeProperty似乎对公共属性进行了筛选,而GetRuntimeProperties没有应用任何筛选器。
有人能合理解释为什么微软决定这些类似的方法应该有不同的行为吗?设计错误
谢谢。
内部GetRuntimeProperty
调用Type.GetProperty(name)
,后者搜索具有指定名称的公共属性。属性Id
受到保护,因此找不到它。
public static PropertyInfo GetRuntimeProperty(this Type type, string name)
{
CheckAndThrow(type);
return type.GetProperty(name);
}
另一方面,GetRuntimeProperties
返回公共和非公共属性
public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type)
{
CheckAndThrow(type);
return type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance);
}
说明:GetRuntimeProperties
的目的是返回所有属性的IEnumerable<PropertyInfo>
集合,让您通过LINQ过滤该集合。您可以选择公共、非公共或任何其他类型的属性。有了GetRuntimeProperty
返回的单个属性,您就不需要这种灵活性,因此它对于大多数常见用途都是受限制的。