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?
LVL 1
Michael SterlingWeb Applications DeveloperAsked:
Who is Participating?
 
Jacques Bourgeois (James Burger)PresidentCommented:
I often overrides ToString and build a string that list all the properties with their values.

		public override string ToString()
		{
			return ("PropertyOne=" + this.PropertyOne.ToString() + ",   " + "PropertyTwo=" + this.PropertyTwo.ToString() + "..." ;
		}

Open in new window


it_saige solution has the big advantage that you do not have to think about modifying it if you ever add properties, and I use it from time to time.

The ToString mechanism requires more work and need to be adjusted if changes are made to the class. But it has a few advantages:

- You have more control over what goes out and what does not.
- You have more control the order in which the properties are displayed. I usually prefer alphabetical.
- You can add other values that are not properties, but could be useful in debugging or diagnosing a problem, such as the values of private variables.
- You can also format everything in a way that can be more appropriate for a specific class. For instance, you might want to group together certain blocks of properties, like what you can do in the Properties window.
0
 
it_saigeDeveloperCommented:
You could always use reflection:
using System;
using System.Text;

namespace EE_Q28668262
{
	class Program
	{
		static void Main(string[] args)
		{
			SomeComplexType wee = new SomeComplexType();
			Console.WriteLine("Unpopulated (default values):");
			Console.WriteLine(wee.GetPropertyValueTable());
			wee = new SomeComplexType() { PropertyOne = "One", PropertyThree = 3, PropertyFive = DateTime.Now, PropertySeven = 7, PropertyNine = 9 };
			Console.WriteLine();
			Console.WriteLine("Populated:");
			Console.WriteLine(wee.GetPropertyValueTable());
			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("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

Produces the following output -Capture.JPG-saige-
0
 
Michael SterlingWeb Applications DeveloperAuthor Commented:
@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.
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
it_saigeDeveloperCommented:
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-
0
 
Michael SterlingWeb Applications DeveloperAuthor Commented:
@saige: Sorry, that's what I get for rushing. Thanks.
0
 
it_saigeDeveloperCommented:
Not a problem.  :)

-saige-
0
 
Michael SterlingWeb Applications DeveloperAuthor Commented:
@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.
0
 
Michael SterlingWeb Applications DeveloperAuthor Commented:
Thanks to you both!
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
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.
0
 
it_saigeDeveloperCommented:
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 -Capture.JPGNote 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-
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.