Dynamically overriding ToString () using Reflection

I usually override the ToString () method to output property names and their associated values. I'm a little tired of writing them manually, so I'm looking for a dynamic solution.

Main:

TestingClass tc = new TestingClass() { Prop1 = "blah1", Prop2 = "blah2" }; Console.WriteLine(tc.ToString()); Console.ReadLine(); 

TestingClass:

 public class TestingClass { public string Prop1 { get; set; }//properties public string Prop2 { get; set; } public void Method1(string a) { }//method public TestingClass() { }//const public override string ToString() { StringBuilder sb = new StringBuilder(); foreach (Type type in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()) { foreach (System.Reflection.PropertyInfo property in type.GetProperties()) { sb.Append(property.Name); sb.Append(": "); sb.Append(this.GetType().GetProperty(property.Name).Name); sb.Append(System.Environment.NewLine); } } return sb.ToString(); } } 

Currently issued:

 Prop1: System.String Prop1 Prop2: System.String Prop2 

Output Required:

 Prop1: blah1 Prop2: blah2 

I am open to other decisions, he should not use reflection, he simply must produce the desired conclusion.

+8
tostring override reflection c #
source share
3 answers

This works for me:

 public class TestingClass { public string Prop1 { get; set; }//properties public string Prop2 { get; set; } public void Method1(string a) { }//method public TestingClass() { }//const public override string ToString() { StringBuilder sb = new StringBuilder(); foreach (System.Reflection.PropertyInfo property in this.GetType().GetProperties()) { sb.Append(property.Name); sb.Append(": "); if (property.GetIndexParameters().Length > 0) { sb.Append("Indexed Property cannot be used"); } else { sb.Append(property.GetValue(this, null)); } sb.Append(System.Environment.NewLine); } return sb.ToString(); } } 

To make it available everywhere, you can create an extension.
It is not possible to override methods in Extension, but still this should simplify your life.

 public static class MyExtensions { public static string ToStringExtension(this object obj) { StringBuilder sb = new StringBuilder(); foreach (System.Reflection.PropertyInfo property in obj.GetType().GetProperties()) { sb.Append(property.Name); sb.Append(": "); if (property.GetIndexParameters().Length > 0) { sb.Append("Indexed Property cannot be used"); } else { sb.Append(property.GetValue(obj, null)); } sb.Append(System.Environment.NewLine); } return sb.ToString(); } } 

Then you can call ToStringExtension() for each object.
The disadvantage is that it does not work perfectly for lists, etc. For example:

 var list = new List<string>(); // (filling list ommitted) list.ToStringExtension(); // output: // Capacity: 16 // Count: 11 // Item: Indexed Property cannot be used 
+17
source share

Here is an extension that will report standard types such as string, int and Datetime, but will also report string lists (shown below in AccessPoints , which failed to process above). Note that the output is aligned, for example:

 Name : Omegaman ID : 1 Role : Admin AccessPoints : Alpha, Beta, Gamma WeekDays : Mon, Tue StartDate : 3/18/2014 12:16:07 PM 

The following is an extension that accepts any type if its class. It then reflects on public and private properties and if they are not null reports.

 public static string ReportAllProperties<T>(this T instance) where T : class { if (instance == null) return string.Empty; var strListType = typeof(List<string>); var strArrType = typeof(string[]); var arrayTypes = new[] { strListType, strArrType }; var handledTypes = new[] { typeof(Int32), typeof(String), typeof(bool), typeof(DateTime), typeof(double), typeof(decimal), strListType, strArrType }; var validProperties = instance.GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(prop => handledTypes.Contains(prop.PropertyType)) .Where(prop => prop.GetValue(instance, null) != null) .ToList(); var format = string.Format("{{0,-{0}}} : {{1}}", validProperties.Max(prp => prp.Name.Length)); return string.Join( Environment.NewLine, validProperties.Select(prop => string.Format(format, prop.Name, (arrayTypes.Contains(prop.PropertyType) ? string.Join(", ", (IEnumerable<string>)prop.GetValue(instance, null)) : prop.GetValue(instance, null))))); } 

Using

myInstance.ReportAllProperties()

Please note that this is based on my C # blog post : ToString to report all the properties even of Private Ones Via Reflection , which provides a more reliable explanation of what is happening.

+2
source share

This is what I found that works with most instance types (including List):

 public static string ToXml(object Obj, System.Type ObjType) { try { XmlSerializer ser; XmlSerializerNamespaces SerializeObject = new mlSerializerNamespaces(); ser = new XmlSerializer((ObjType)); MemoryStream memStream; memStream = new MemoryStream(); XmlTextWriter xmlWriter; xmlWriter = new XmlTextWriter(memStream, Encoding.UTF8); xmlWriter.Namespaces = true; XmlQualifiedName[] qualiArrayXML = SerializeObject.ToArray(); ser.Serialize(xmlWriter, Obj); xmlWriter.Close(); memStream.Close(); string xml; xml = Encoding.UTF8.GetString(memStream.GetBuffer()); xml = xml.Substring(xml.IndexOf(Convert.ToChar(60))); xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1)); return xml; } catch (Exception ex) { return string.Empty; } } 

using:

 string classAasString = ClassToXml.ToXml(a, typeof(ClassA)); //whare ClassA is an object 
0
source share

All Articles