views:

3110

answers:

1

I have a class that creates a static array of all properties, using a static constructor. I also have a function -- GetNamesAndTypes() -- that lists the name & type of each property in that array.

Now I want to create another instance-level function -- GetNamesAndTypesAndValues() -- that displays the name & type of each property in the class, as well as that instance's value. How would I do that? Here's the code that I've written so far:

//StaticTest.cs
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;

namespace StaticTest
{
 public class ClassTest
 {
  private string m_A, m_B, m_C;
  private static PropertyInfo[] allClassProperties;

  static ClassTest()
  {
   Type type = typeof(ClassTest);
   allClassProperties = type.GetProperties();

   // Sort properties alphabetically by name (http://www.csharp-examples.net/reflection-property-names/)
   Array.Sort(allClassProperties, delegate(PropertyInfo p1, PropertyInfo p2)
   {
    return p1.Name.CompareTo(p2.Name);
   });
  }

  public int A
  {
   get { return Convert.ToInt32(m_A); }
   set { m_A = value.ToString(); }
  }

  public string B
  {
   get { return m_B; }
   set { m_B = value; }
  }

  public DateTime C
  {
   get { return DateTime.ParseExact("yyyyMMdd", m_C, CultureInfo.InvariantCulture); }
   set { m_C = String.Format("{0:yyyyMMdd}", value); }
  }

  public static void GetNamesAndTypes()
  {
   foreach (PropertyInfo propertyInfo in allClassProperties)
   {
    Console.WriteLine("{0} [type = {1}]", propertyInfo.Name, propertyInfo.PropertyType);
   }
  }

  public void GetNamesAndTypesAndValues()
  {
   foreach (PropertyInfo propertyInfo in allClassProperties)
   {
    Console.WriteLine("{0} [type = {1}]", propertyInfo.Name, propertyInfo.PropertyType);
   }
  }
 }
}

//Program.cs
using System;
using System.Collections.Generic;
using StaticTest;

namespace ConsoleApplication2
{
 class Program
 {
  static void Main(string[] args)
  {
   Console.WriteLine("[static] GetNamesAndTypes()");
   ClassTest.GetNamesAndTypes();
   Console.WriteLine("");

   ClassTest classTest = new ClassTest();
   classTest.A = 4;
   classTest.B = @"bacon";
   classTest.C = DateTime.Now;
   Console.WriteLine("[instance] GetNamesAndTypesAndValues()");
   classTest.GetNamesAndTypesAndValues();

   Console.ReadLine();
  }
 }
}

I tried using propertyInfo.GetValue(), but I couldn't get it to work.

+2  A: 

In you example propertyInfo.GetValue(this, null) should work. Consider altering GetNamesAndTypesAndValues() as follows:

        public void GetNamesAndTypesAndValues()
        {
                foreach (PropertyInfo propertyInfo in allClassProperties)
                {
                        Console.WriteLine("{0} [type = {1}] [value = {2}]", propertyInfo.Name, propertyInfo.PropertyType, propertyInfo.GetValue(this, null));
                }
        }
Yannick M.
While fine for normal simple properties, this will fail with indexer properties, which take a non-null argument list as specified by PropertyInfo.GetIndexParameters.
Steve Gilham
Thank you!
AspNyc