Filtering object properties by name

I am doing some simple checks on different types. The current test I'm working on is checking that their properties are populated. In this case, the occupancy is defined as non-null, having a length greater than zero (if a string) or not equal to 0 (if an integer).

The "difficult" part of this test is that some properties are immune to this test. Right now I'm using a giant if statement that will rip off properties that I don't need to check.

//Gets all the properties of the currect feature.
System.Reflection.PropertyInfo[] pi = t.GetProperties();

for(int i = 0; i < pi.Length; i++)
{
    if(!pi[i].Name.Equals("PropertyOne") 
    && !pi[i].Name.Equals("PropertyTwo") 
    && !pi[i].Name.Equals("PropertyThree") 
            //... repeat a bunch more times
    && !pi[i].Name.IndexOf("ValueOne") != -1 
    && !pi[i].Name.IndexOf("ValueTwo") != -1 
            //... repeat a bunch more times
    {
        //Perform the validation check.
    }                 
}

      

While profiling, I noticed that the if statement is indeed worse than reflection (not that reflection flashes quickly). Is there a more efficient way to filter properties of several different types?

I was thinking about a massive regex, but I'm not sure how to format it, plus it will probably be unreadable given its size. I also considered storing the values ​​in a list and then using Linq, but I'm not sure how to handle the cases that use String.IndexOf () to determine if a property contains a specific value.

Thanks in advance.

+1


source to share


3 answers


Create a "Exact Names" HashSet with PropertyOne, PropertyTwo, etc., and then a list of "partialNames" with ValueOne, ValueTwo, and so on. Then:

var matchingProperties = pi.Where(exactNames.Contains(pi.Name) ||
                          partialNames.Any(name => pi.Name.Contains(name));

foreach (PropertyInfo property in matchingProperties)
{
    // Stuff
}

      



(Odd indentation to avoid wrapping.)

Note that you can cache a set of properties for validation based on each type, so you only need to pass this validation once for each type.

+2


source


Your idea will help speed up my program, thanks. However, you had some syntax problems and also matched the items found in the lists and I needed the items that are not in the list. Here is the code I used.



List<System.Reflection.PropertyInfo> pi = type.GetProperties().ToList();

var matchingProperties = pi.Where( prop => !PropertyExclusionSet.Contains( prop.Name )
&& !PropertiesPartialSet.Any( name => prop.Name.Contains( name ) ) );

      

0


source


You might consider decorating your properties with attributes that tell you what to do with them.

public class MyClass {

   [CheckMe]
   public int PropertyOne { get; set; }

   [DontCheckMe]
   public int PropertyTwo { get; set; }

}

      

0


source







All Articles