我正在尝试获取具有私有设置器的类的所有属性。这看起来很简单,但是我遇到了一种奇怪但可能正常的行为。
这是我实施的解决方案
public static IEnumerable<PropertyInfo> InstanceProperties(this Type type) {
List<PropertyInfo> results = new();
var allProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in allProperties) {
var setMethod = property.GetSetMethod(true);
if (setMethod != null && setMethod.IsPrivate) {
results.Add(property);
}
}
return results;
}
我也创建了一些简单的类用于测试
public class BaseClass {
public string Name { get; private set; }
public BaseClass(string name) {
Name = name;
}
}
public class DerivedClass : BaseClass {
public string Description { get; private set; }
public DerivedClass(string name, string description) : base(name) {
Description = description;
}
}
为了测试这个,我正在使用
[Fact]
public void InstanceProperties_WithBaseType_ReturnsAllProperties() {
// Arrange
Type baseEntityType = typeof(BaseClass);
// Act
var result = baseEntityType.InstanceProperties();
// Assert
result.Should().NotBeNullOrEmpty();
result.Count().Should().Be(1);
}
[Fact]
public void InstanceProperties_WithDerivedType_ReturnsAllProperties() {
// Arrange
Type baseEntityType = typeof(DerivedClass);
// Act
var result = baseEntityType.InstanceProperties();
// Assert
result.Should().NotBeNullOrEmpty();
result.Count().Should().Be(2);
}
第一次测试成功,第二次测试失败。更具体地说,在第二个测试中,代码 var
allProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
返回两个属性,但基类的属性没有 setter 方法。这与第一个测试不太一致,因为在这种情况下,该属性确实有一个被定义为私有的 set 方法。
对此行为有什么建议/解释吗?
编辑 根据评论的建议,我更好地解释了问题的范围。最终目标是构造具有以下特征的某些类型的对象:
Entity
)继承的类,这些基类具有带有私有设置器的 Guid 类型的单个唯一实例属性Entity
Create
的公共静态工厂方法,当然每个类都有不同的参数我想了解实体框架如何处理这种构造技术,它使用私有无参数构造函数来创建对象实例。
这可能就像一些递归一样简单,如果该类型具有基本类型,请将这些属性添加到您的列表中:
public static IEnumerable<PropertyInfo> InstanceProperties(this Type type)
{
List<PropertyInfo> results = new();
var allProperties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var property in allProperties)
{
var setMethod = property.GetSetMethod(true);
if (setMethod != null && setMethod.IsPrivate)
{
results.Add(property);
}
}
if(type.BaseType != null)
{
results.AddRange(type.BaseType.InstanceProperties());
}
return results;
}
在这个特定示例中,这给出了您预期的
2
输出,但可能需要一些调整才能满足您的确切期望。