Получить путем отражения свойств класса с помощью частных установщиковC#

Место общения программистов C#
Ответить
Anonymous
 Получить путем отражения свойств класса с помощью частных установщиков

Сообщение Anonymous »

Я пытаюсь получить все свойства класса, у которых есть частный установщик. Это кажется очень простым, однако я столкнулся со странным, но, вероятно, нормальным поведением.
Это решение, которое я реализовал
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
Мне хотелось бы понять, как этот метод построения обрабатывается Entity Framework, которая использует закрытый конструктор без параметров для создания экземпляров объектов.РЕДАКТИРОВАНИЕ 2
В итоге я написал решение, которое очень похоже на два, представленные Джеймиком и Гертом Арнольдом. Пишу сюда для справки. Всем спасибо!
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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»