Ответ 1
Я предполагаю, что вы пытаетесь определить универсальный способ "сбрасывать" объект, ничего не зная о его структуре. Если это так, то вы делаете все правильно. Вы используете отражение (GetType()
и связанные методы класса Type
) для проверки объекта и возврата его информации.
Причина GetFields()
ничего не вернула, так это то, что вы, скорее всего, не указали правильные флаги привязки. В частности, если вы вызываете перегрузку, которая не принимает никаких параметров, вы возвращаете только теги public
; если вам нужны частные поля, вам нужно их специально спросить.
В вашем случае GetFields(BindingFlags.NonPublic)
вернет вам поля _new_systemGauges
и _new_systemAlarm
, а GetProperties() вернет вам свойства New_systemAlarm
и New_systemAlarm
.
Другим ключевым элементом, который вы пропустили, является то, что возвращаемые вами данные - это метаданные типа; он определяет структуру class
, а не какой-либо конкретный экземпляр. Если вы хотите знать, что значение свойства для конкретного экземпляра, вы должны спросить об этом:
foreach (var prop in obj.GetType().GetProperties())
{
Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(obj, null));
}
У вас есть один из элементов PropertyInfo
из метаданных типа, вы можете запросить это значение свойства в любом экземпляре этого типа. Он не должен быть тем же самым экземпляром, который вы изначально использовали. Например:
var objs = somelist.Where(x => x.Id == 1);
foreach (var prop in objs.First().GetType().GetProperties())
{
int x = 0;
foreach (var obj in objs)
{
if (prop.PropertyType.Name.Equals("Int32"))
{
int val = (int)prop.GetValue(obj, null);
Console.WriteLine("Obj #{0}: {1} = 0x{2:x8}", x++, prop.Name, val);
}
else if (prop.PropertyType.Name.Equals("Decimal"))
{
int val = (decimal)prop.GetValue(obj, null);
Console.WriteLine("Obj #{0}: {1} = {2:c2}", x++, prop.Name, val);
}
else
{
Console.WriteLine("Obj #{0}: {1} = '{2}'", x++, prop.Name, prop.GetValue(obj, null));
}
}
}
Технически вы должны проверить результат GetIndexParameters
, чтобы узнать, проиндексировано ли свойство или нет; параметр null
для GetValue
на самом деле является массивом значений индекса.
Чтобы преобразовать возвращаемое значение, вы можете либо использовать приемы типа, либо если вы хотите быть более гибким, используйте методы класса Convert. Разница заключается, например, в том, что если у вас есть свойство short
, GetValue()
будет возвращать коробочное короткое число, которое вы не можете тогда typecast как int
; вам нужно сначала распаковать его на short
. Использование Convert.ToInt32()
выполнит все необходимые шаги, чтобы получить значение int
из любого свойства, которое можно конвертировать в целое число.
Преобразование между ссылочными типами проще, поскольку для этого можно просто использовать is
и as
; они работают так же, как вы ожидали бы с "отраженными" значениями свойств.