samedi 1 janvier 2022

How to detect the length of array property using reflection only if it actually is an array?

I'm converting an object based on reflection like this.

obj.GetType().GetProperties()

It produces the expected list of properties.

{System.Reflection.PropertyInfo[4]}
[0]: {System.String Name}
[1]: {System.Guid[] Ids}
[2]: {System.String[] Tags}
[3]: {System.Nullable`1[System.Boolean] Status}

Then, I want to clear the list of properties not in use, so I add the condition that a value of a property needs to differ from null.

obj.GetType().GetProperties()
  .Where(a => a.GetValue(obj) != null)

It produces the expected result for atomary fields but not the arrays (as they're undefinably not null, only empty).

{System.Linq.Enumerable.WhereArrayIterator<System.Reflection.PropertyInfo>}
[0]: {System.String Name}
[1]: {System.Guid[] Ids}
[2]: {System.String[] Tags}

I'm not sure how I should go about detecting non-null but empty array properties in order to exclude those. I can't simply cast to an array (as discussed here) because not every property is an array.

The closest approach I have is this piece of "work", which seems to be rather... undesired. It's got this distinct code smell going on.

obj.GetType().GetProperties()
  .Where(a => a.GetValue(obj) != null 
    && !(a.GetValue(obj) is Array && (a.GetValue(obj) as Array).Length == 0))

And as I try to create something with it using Select(a=>a.GetValue(obj)) it gets even clunkier and more obviously in desperate need of improvement. I also noticed that whenever the array isn't empty, my mapping fails producing System.String%5b%5d, which will probably require me to additionally clunkify the code.





Aucun commentaire:

Enregistrer un commentaire