简体   繁体   中英

How do I use reflection to get a list of values of an object's fields that match a particular type?

Please note that for conciseness and readability, I've substituted types, fields, and methods that are more simple to work with.

I've defined a boolean property, personProperty for a class, Person , in which I want the getter, get{} to call a private method, personMethod(int arg) on each integer field value that's defined in Person (in this case _age , _phoneNumber ). It should ignore all other types like readingList .

This is so that if I were to add another integer field to Person (or modify or delete any Person field names), I would not have to update the definition of personProperty which, by design choice, depends on all integer fields of the Person class (ie, it is never the case that the developer will introduce an int field that he doesn't want personMethod to run against).

public Class Person
{
   private int _age;
   public int _phoneNumber;
   // protected int _futureInt;
   Dictionary<string, string> _readingList = new Dictionary<string, string>();

   public bool personProperty
   {
       get
       {
           // ...
           bool personPropertyReturnValue; 
           List<bool> resultList = new List<bool>();
           foreach(int personFieldValue in LISTOFPERSONINTS)
           {
               bool result = personMethod(personFieldValue);
               resultList.Add(result);
           }
           // Do stuff with `resultList` that'll initialize personPropertyReturnValue;
           return personPropertyReturnValue;
       }
   }

    private bool personMethod(int arg)
    {
       bool returnValue = true;
       // Do stuff to initialize `returnValue`
       return returnValue;
    }
}

I need to know what I should substitute for LISTOFPERSONINTS so that it returns an iterable over the values stored in _age , _phoneNumber (and all other future int , like _futureInt defined in Person ).

I don't think that using reflection would be better than adjusting your property each time you add a field, but there you go:

public class Person
{
    private int _age;
    public int _phoneNumber;
    // protected int _futureInt;
    Dictionary<string, string> _readingList = new Dictionary<string, string>();

    public Person(int age){
        _age = age;
    }

    public bool personProperty
    {
        get
        {
            List<bool> resultList = new List<bool>();
            var intFields = this.GetType().GetFields(BindingFlags.Instance | 
                                                     BindingFlags.NonPublic | 
                                                     BindingFlags.Public)
                                          .Where(f => f.FieldType == typeof(int))
                                          .Select(f => f.GetValue(this)).Cast<int>();
            foreach (int personFieldValue in intFields)
            {
                bool result = personMethod(personFieldValue);
                resultList.Add(result);
            }
            // Do stuff with `resultList` that'll initialize personPropertyReturnValue;
            bool personPropertyReturnValue = resultList.All(b => b);
            return personPropertyReturnValue;
        }
    }

    private bool personMethod(int arg)
    {
        return (arg > 0);
    }
}

Test:

var person1 = new Person(0);
Console.WriteLine(person1.personProperty);   // False

var person2 = new Person(1);
Console.WriteLine(person2.personProperty);   // False

var person3 = new Person(1) { _phoneNumber = 1 };
Console.WriteLine(person3.personProperty);   // True

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM