#c#
Вопрос:
У меня есть эти занятия:
public class Foo
{
public Bar bar;
}
public class Bar
{
public List<int> Something { get; set; }
public string Else { get; set; }
}
У меня много таких занятий Foo
. Все они содержат ровно одно поле. Это поле, Bar
в моем примере, каждый раз будет объектом другого типа, оно не обязательно должно иметь тип Bar
. Каким бы объектом это ни было ( Bar
или иным образом), это поле всегда будет объектом, имеющим два свойства, Something
и Else
.
Моя задача: учитывая любой объект, подобный Foo (с одним полем, содержащим два свойства), получите значение двух свойств. Учитывая этот метод:
public void DoStuff(object myObject)
{
var asdf = myObject.GetType().GetFields().First();
}
Я могу получить информацию о поле для бара. То, что я ищу, — это ценности Something
и Else
. Названия этих свойств никогда не меняются. Каким бы ни был тип поля, у него всегда будут два имени свойств Something
, и они будут одного и Else
того же типа.
К сожалению, моя проблема связана с автоматически сгенерированным кодом, и нет общих интерфейсов или базовых типов, которые я мог бы легко использовать.
Комментарии:
1. И я предполагаю, что тип
Something
всегда aList<int>
иElse
всегда astring
?2. @Sweeper Это правильно. Я уточню вопрос.
Ответ №1:
Используя этот код, вы можете получить PropertyInfo
s для Something
и для Else
свойства:
Foo myObject = new Foo { bar = new Bar() };
// the FieldInfo for Foo.bar
var barField = myObject.GetType().GetFields().First();
// the Bar instance, i.e. myObject.bar
var barValue = barField.GetValue(myObject);
var somethingProperty = barField.FieldType.GetProperty("Something", BindingFlags.Instance | BindingFlags.Public);
var elseProperty = barField.FieldType.GetProperty("Else", BindingFlags.Instance | BindingFlags.Public);
как отметил PsiHamster, затем вы можете использовать GetValue
и SetValue
для извлечения и установки значений somethingProperty
и elseProperty
подобных этому:
// get the value
var somethingValue = somethingProperty.GetValue(barValue);
// set the value
somethingProperty.SetValue(barValue, new List<int>());
Комментарии:
1. На самом деле свойство поддерживает
GetValue()
метод, поэтому вам не нужно самостоятельно вызывать методы2. Спасибо, это блестяще работает. Теперь мне не нужно писать более 1000 строк конфигурации автомата. Огромное спасибо.
3. @yesman Рад слышать, что это помогает. Если вы действительно используете это в производстве, пожалуйста, обязательно подумайте о кэшировании
FieldInfo
иPropertyInfo
s, чтобы вы не вызывалиGetFields()
иGetProperty()
для каждого объекта.
Ответ №2:
//Get Bar FieldInfo
var barFieldInfo = myObject.GetType().GetFields().First();
// Get all public instance properties info
var barProps = barFieldInfo.FieldType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
// Get Something and Else properties info
var smthPropInfo = barProps.First(prop => prop.Name == nameof(Bar.Something));
var elsePropInfo = barProps.First(prop => prop.Name == nameof(Bar.Else));
// Get values
var bar = barFieldInfo.GetValue(myObject);
var smth = smthPropInfo.GetValue(bar);
var else = elsePropInfo.GetValue(bar);