Link to home
Start Free TrialLog in
Avatar of Michael Sterling
Michael SterlingFlag for United States of America

asked on

How do I access / print all the property values of my custom object?

I have created a custom obj. with about 30 properties. I'm having trouble doing an update to my database and I think that it may be due to a property's value. How can I loop through the property values of all the properties of my object, append them to a string and then print them?
SOLUTION
Avatar of it_saige
it_saige
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Michael Sterling

ASKER

@it_saige: I don't have that method available to me for my object, for some reason and hovering over it doesn't give me the option to add the library (using) that will allow me access to that method for my object.

@Jacques Bourgeois (James Burger): I may have to try that, thank you.
It's because I made the method.

If you look at my example, I created a static class called Extensions and added a generic method to it called GetPropertyValueTable.
static class Extensions
{
	public static string GetPropertyValueTable<T>(this T source)
	{
		StringBuilder sb = new StringBuilder();
		sb.AppendLine("Property\t\tValue");
		sb.AppendLine("--------\t\t-----");
		try
		{
			foreach (var prop in source.GetType().GetProperties())
			{
				if (prop.CanRead)
					sb.AppendLine(string.Format("{0}\t\t{1}", prop.Name, (prop.GetValue(source, null) != null) ? prop.GetValue(source, null) : "Value is null or empty"));
				else
					sb.AppendLine(string.Format("{0}\t\tProperty Unreadable", prop.Name));
			}
		}
		catch (Exception ex)
		{
			sb.AppendLine(string.Format("Exception reported in {0} - {1} [{2}]", ex.Source, ex, ex.Message));
		}
		return sb.ToString();
	}
}

Open in new window

-saige-
@saige: Sorry, that's what I get for rushing. Thanks.
Not a problem.  :)

-saige-
@it_saige: I was struggling to figure out why the method above still wasn't returning anything. The reason is because you actually are using getters and setters for your properties which is probably best practices. I'm taking over code that was written by someone else and he didn't use best practices, so the "properties" of his class are just inline type variable declarations which he sets during the initialization of the object. Thank you though, I will keep this in mind / handy should I need it.
Thanks to you both!
Note that you do not have to explicitly code the getter and setter.

The last few versions of C# have Auto-Implemented properties:

     public string Name { get; set; }

The getter and setter are automatically implemented for you by the compiler. You implement your own getter and setter only when you have some processing to perform when assigning or retrieving the value from the private member.

This makes creating properties as simple as declaring variables, but is a better practice. It will more easily maintain compatibility should you ever find the need to intervene on a class member that did not require processing in previous versions of the class.
While what James states is true, realize that in the ultimate scheme of things properties contain at least a getter and/or a setter method, fields do not.

Consider the following example that illustrates the difference:
using System;
using System.Text;
using System.ComponentModel;
using System.Reflection;

namespace EE_Q28668262
{
	class Program
	{
		static void Main(string[] args)
		{
			SomeComplexType wee = new SomeComplexType() { PropertyOne = "One", PropertyThree = 3, PropertyFive = DateTime.Now, PropertySeven = 7, PropertyNine = 9 };
			Console.WriteLine("Properties - Populated:");
			Console.WriteLine(wee.GetPropertyValueTable());
			Console.WriteLine();
			Console.WriteLine("Fields - Populated:");
			Console.WriteLine(wee.GetFieldValueTable());
			Console.ReadLine();
		}
	}

	class SomeComplexType
	{
		private string fPropertyOne = default(string);
		private int fPropertyTwo = default(int);
		private decimal fPropertyThree = default(decimal);
		private long fPropertyFour = default(long);
		private DateTime fPropertyFive = default(DateTime);
		private string fPropertySix = default(string);
		private int fPropertySeven = default(int);
		private decimal fPropertyEight = default(decimal);
		private long fPropertyNine = default(long);
		private DateTime fPropertyTen = default(DateTime);

		public string PropertyOne 
		{ 
			get { return fPropertyOne; } 
			set
			{
				if (!value.Equals(fPropertyOne))
					fPropertyOne = value;
			}
		}

		public int PropertyTwo 
		{ 
			get { return fPropertyTwo; } 
			set
			{
				if (!value.Equals(fPropertyTwo))
					fPropertyTwo = value;
			}
		}

		public decimal PropertyThree 
		{ 
			get { return fPropertyThree; } 
			set
			{
				if (!value.Equals(fPropertyThree))
					fPropertyThree = value;
			}
		}

		public long PropertyFour 
		{ 
			get { return fPropertyFour; } 
			set
			{
				if (!value.Equals(fPropertyFour))
					fPropertyFour = value;
			}
		}

		public DateTime PropertyFive 
		{ 
			get { return fPropertyFive; } 
			set
			{
				if (!value.Equals(fPropertyFive))
					fPropertyFive = value;
			}
		}

		public string PropertySix 
		{ 
			get { return fPropertySix; } 
			set
			{
				if (!value.Equals(fPropertySix))
					fPropertySix = value;
			}
		}

		public int PropertySeven 
		{ 
			get { return fPropertySeven; } 
			set
			{
				if (!value.Equals(fPropertySeven))
					fPropertySeven = value;
			}
		}

		public decimal PropertyEight 
		{ 
			get { return fPropertyEight; } 
			set
			{
				if (!value.Equals(fPropertyEight))
					fPropertyEight = value;
			}
		}

		public long PropertyNine 
		{ 
			get { return fPropertyNine; } 
			set
			{
				if (!value.Equals(fPropertyNine))
					fPropertyNine = value;
			}
		}

		public DateTime PropertyTen 
		{ 
			get { return fPropertyTen; } 
			set
			{
				if (!value.Equals(fPropertyTen))
					fPropertyTen = value;
			}
		}
	}

	static class Extensions
	{
		public static string GetPropertyValueTable<T>(this T source)
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine(FormattedLine("Property", "Value"));
			sb.AppendLine(FormattedLine("--------", "-----"));
			try
			{
				foreach (var prop in source.GetType().GetProperties())
				{
					if (prop.CanRead)
						sb.AppendLine(FormattedLine(prop.Name, (prop.GetValue(source, null) != null) ? prop.GetValue(source, null) : "Value is null or empty"));
					else
						sb.AppendLine(FormattedLine(prop.Name, "Property Unreadable"));
				}
			}
			catch (Exception ex)
			{
				sb.AppendLine(string.Format("Exception reported in {0} - {1} [{2}]", ex.Source, ex, ex.Message));
			}
			return sb.ToString();
		}

		public static string GetFieldValueTable<T>(this T source)
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine(FormattedLine("Field", "Accessibility", "Value"));
			sb.AppendLine(FormattedLine("-----", "-------------", "-----"));
			try
			{
				foreach (var field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
					sb.AppendLine(FormattedLine(field.Name, field.Attributes, (field.GetValue(source) != null) ? field.GetValue(source) : "Value is null or empty"));
			}
			catch (Exception ex)
			{
				sb.AppendLine(string.Format("Exception reported in {0} - {1} [{2}]", ex.Source, ex, ex.Message));
			}
			return sb.ToString();
		}

		public static string FormattedLine(params object[] args)
		{
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < args.Length; i++)
				sb.Append(string.Format("{0, -25}", args[i]));
			return sb.ToString();
		}
	}
}

Open in new window

Produces the following output -User generated imageNote that Properties can also be marked with additional accessibility properties however, in general, properties are marked as public while their fields are marked as private.

-saige-