Цикл на GetFields и GetProperties типа? - PullRequest
2 голосов
/ 02 декабря 2011

Вот мой код:

var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
    //some code
}

var props = type.GetProperties();
foreach (PropertyInfo prop in props)
{
    //exact same code
}

Я знаю, что могу создать функцию, которую я мог бы вызвать дважды, но то, что я хотел бы сделать (если это возможно), это один foreach.Примерно так (да, код не работает. Если бы он работал, я бы не стал задавать вопрос!):

var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
var props = type.GetProperties();

foreach (PropertyInfo prop in fields && PropertyInfo prop in props)
{
    //some code
}

Я действительно чувствую, что есть способ, даже если я знаю, чтомое решение далеко не компилируемо: (
Спасибо за любую помощь!

Ответы [ 4 ]

3 голосов
/ 02 декабря 2011

Если вы в порядке со свойствами, предоставляемыми классом MemberInfo (который является базовым для FieldInfo и PropertyInfo), вы можете сделать следующее:

var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance).Cast<MemberInfo>();
var props = type.GetProperties().Cast<MemberInfo>();
var fieldsAndProperties = fields.Union(props);

foreach (MemberInfo mi in fieldsAndProperties)
{
...
}
1 голос
/ 02 декабря 2011

Чтобы поместить их в один цикл:

foreach (MemberInfo member in fields.Cast<MemberInfo>().Concat(props))
{ 
    //I'm 100% sure this isn't what you want
    //because you need to set value here
    //in this case, you still need to check if member is a FieldInfo/PropertyInfo 
    //and then convert it before you set the values
}

На самом деле, использование двух циклов, вероятно, здесь лучше.Во-первых, код выглядит более понятным, потому что они делают разные вещи, один устанавливает значения полей, а другой - для свойств.Во-вторых, регистрация кэшей, вероятно, помогает сделать вашу программу немного быстрее, чем один цикл.

1 голос
/ 02 декабря 2011

Если функциональность, предоставляемая MemberInfo, достаточна для вас в цикле, вы можете объединить поля и свойства в одном и том же массиве или другом перечислимом и выполнять итерацию только один раз.

Это возможно, поскольку оба FieldInfo и PropertyInfo наследуются от класса MemberInfo.

Пример кода:

var fields = typeof(DateTime).GetFields(
    BindingFlags.Public | BindingFlags.Instance);

var properties = typeof(DateTime).GetProperties(
    BindingFlags.Public | BindingFlags.Instance);

var all = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>());

foreach (MemberInfo mi in all)
{
    //some code
}
0 голосов
/ 02 декабря 2014

Хммм ....

Этот тип итерации теряет порядок полей и свойств.Например,

class Test
{
    public String tests { get; set; }
    public int    testi;
}

Если GetFields, если получить первым - мы получаем "testi" в качестве первого члена и через GetProperies мы получаем "тесты".Возможно, Union объединит их, но порядок не сохранится.

Есть ли способ получить поля и свойства и сохранить их порядок?

...