Это решение, которое я реализовал
public static IEnumerable
InstanceProperties(this Type type) {
List 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); возвращает два свойства, однако свойство базового класса не имеет метода установки. Это не совсем соответствует первому тесту, так как в этом случае свойство имеет метод set, который определен как частный.
Есть какие-нибудь предложения/объяснения по поводу такого поведения?РЕДАКТИРОВАТЬ
В соответствии с предложениями комментариев я лучше объясню суть вопроса. Конечная цель – создать некоторые типы объектов, которые имеют следующие характеристики:
- Могут быть классами, наследующими непосредственно от хорошо известного базового класса (например, Entity), которые имеют единственное уникальное свойство экземпляра типа Guid с частным установщиком.
- Могут быть классами, наследующими от абстрактного базового класса, который, в свою очередь, наследуется от Entity.
Все свойства экземпляра имеют частный установщик. - Все классы имеют один общедоступный статический фабричный метод Create, конечно же, с разными параметрами для каждого. class
В итоге я написал решение, которое очень похоже на два, представленные Джеймиком и Гертом Арнольдом. Пишу сюда для справки. Всем спасибо!
public static IEnumerable InstanceProperties(this Type type) {
List results = new();
Type? leafType = type;
while (leafType != null) {
var allProperties = leafType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in allProperties) {
var accessors = property
.GetAccessors(true)
.Where(a => a.ReturnType == typeof(void) && a.IsPrivate)
.ToArray();
foreach (var accessor in accessors) {
results.Add(property);
}
}
leafType = leafType.BaseType;
}
return results;
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... te-setters
Мобильная версия