Question

Here is my code :

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
}

I know I can create a function that I could call twice but what I'd like to do (if possible) is a single foreach. Something like this (yes, the code doesn't work. If it worked, I wouldn't ask the question !):

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

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

I really feel like there is a way, even if I know that my solution is far from being compilable :(
Thanks for any help !

Was it helpful?

Solution

If you're OK with properties exposed by MemberInfo class (which is base for both FieldInfo and PropertyInfo) then you may do the following:

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)
{
...
}

OTHER TIPS

If the functionality exposed by MemberInfo is sufficient for you in the loop then you can concatenate both fields and properties on the same array or other enumerable and iterate only once.

This is possible because both FieldInfo and PropertyInfo inherit from the MemberInfo class.

Sample code:

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
}

To put them into one loop:

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
}

Actually, using two loops is probably better here. Firstly the code looks clearer, because they are doing different things, one sets values of fields and another is for properties. Secondly, register caches probably helps to make your program a little faster than one loop.

Hmmm....

This kind of iteration is loosing order of fields and properties. E.g.

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

If GetFields if get first - we get "testi" as first memberm and via GetProperies we get "tests". Union probably will merge them but order is not preserved.

Is there any way to get fields and properties and preserve order of them ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top