Sunday, 2 July 2017

Reflection 02 Binding flags

To get member data using reflection you have to remember to match all binding flags, if a property is instance and public, but you only request public or instance it will not show up.

using System;
using System.Diagnostics;
using System.Reflection;
using System.Collections.Generic;
namespace pc.reflection01
{
    [DebuggerDisplay("{DebuggerDisplay()}")]
    class Person
    {
        static int _runningId = 0;
        public int Id { get; } = _runningId++;
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime Birthdate { get; set; }
        public Person() { }
        public Person(string FirstName, string LastName)
            : this()
        {
            this.FirstName = FirstName;
            this.LastName = LastName;
        }
        public Person(string FirstName, string LastName, DateTime Birthdate)
            : this(FirstName, LastName)
        {
            this.Birthdate = Birthdate;
        }

        public int GetAge()
        {
            if (Birthdate == new DateTime())
                return -1;

            var today = DateTime.Now;
            var age = today.AddYears(-Birthdate.Year).Year;
            return Birthdate.AddYears(age) > today ? --age : age;
        }

        private string DebuggerDisplay()
        {
            var age = GetAge();
            var result = $"{FirstName} {LastName}";
            return age > -1 ? $"{result} is {age}" : result;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<MemberInfo> members =
                     typeof(Person).GetMembers( BindingFlags.NonPublic |
                                                BindingFlags.Static |
                                                BindingFlags.GetField);

            foreach (MemberInfo mi in members)
                Console.WriteLine(mi.Name);
        }
    }

}

for example by default when inspecting members of a class you private static fields will not be exposed, so you have to specify to see them.

Now reflection is pretty cool and there's way more of it than i want to get into, nor am i an expert in refection however i do think it's valuable to share the only time i've used refection in the real world. and that's for testing, namely testing private functions.