0

I have a class

class ABC
{
    Public int one = 10;
    Public String two = "123";
  public override string ToString()
   {
   }
}

My question i want to get fields information/values in String of Class "ABC" when ever i will create an object of that class. For example:

Public Class Test
{
    public static void Main()
    {
        ABC a = new ABC();
        a.ToString();
    }
}

Now here I create an object a of class "ABC", then i want to override method of ToString() to get all fields values of class ABC in a string.

As solution this worked for me :

**Here is an other solution if we use static fields and fieldsInfo:** 

class ReflectionTest
{
    public static int Height = 2;
    public static int Width = 10;
    public static int Weight = 12;
    public static string Name = "Got It";

    public override string ToString()
    {
        string result = string.Empty;
        Type type = typeof(ReflectionTest); 
        FieldInfo[] fields = type.GetFields();
        foreach (var field in fields)
        {
            string name = field.Name; 
            object temp = field.GetValue(null);
            result += "Name:" + name + ":" + temp.ToString() + System.Environment.NewLine;
        }
        return result;
    }

}
AHMAD SUMRAIZ
  • 535
  • 8
  • 21
  • 3
    Why not just override `ABC.ToString()` to return what you want? – Sean Jan 23 '14 at 12:46
  • @Sean, manually returning "desired properties" does not scale well. – Andrei V Jan 23 '14 at 12:50
  • @AndreiV - who said anything about retaining them? – Sean Jan 23 '14 at 12:52
  • 2
    @AndreiV arguably reflection and concatanating strings every time doesn't either – owenrumney Jan 23 '14 at 12:54
  • @Sean, I'm confused then. He does say that he wants to overwrite the `ToString()` method. There are two possibilities: manually writing "key/value" pairs containing "property name/property value" or dynamically getting the properties and their values using reflection. Am I wrong? What did you have in mind? – Andrei V Jan 23 '14 at 12:54
  • @owen79, I can't say I disagree. There's a trade off between programmer laziness (let's call it scalability) and program execution time. – Andrei V Jan 23 '14 at 12:56

8 Answers8

1
public override string ToString()
{
    Dictionary<string, string> fieldValues = new Dictionary<string, string>();
    var fields = this.GetType().GetFields();

    foreach (var field in fields)
    {
        fieldValues[field.Name] = field.GetValue(this).ToString();
    }

    return string.Join(", ", fieldValues.Select(x => string.Format("{0}: {1}", x.Key, x.Value)));
}
Abbas
  • 14,186
  • 6
  • 41
  • 72
Mark
  • 1,360
  • 1
  • 8
  • 14
0

not sure if this is what you mean;

public override ToString() 
{
    return string.Format("one: {1}{0}two: {2}", Environment.NewLine(), one, two);
}
Abbas
  • 14,186
  • 6
  • 41
  • 72
owenrumney
  • 1,520
  • 3
  • 18
  • 37
0

You could either use a property to retrieve the string, or override ToString(), both are shown:

public class ABC
{
    private Int32 _one = 10;
    public Int32 One { get { return _one; } }
    private String _two = "123";
    public String Two { get { return _two; } }

    protected override ToString()
    {
        return _two;
    }
}
DonBoitnott
  • 10,787
  • 6
  • 49
  • 68
  • 2
    I don't think the problem is overriding `ToString`. I think the question is rather "How do I enumerate all fields of a class using reflection and then create a string from them`. – Thorsten Dittmar Jan 23 '14 at 12:51
0

This should do it:

public override string ToString() {
    string s = "";
    foreach(FieldInfo f in this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)) {
        s += f.Name + "=" + f.GetValue(this).ToString() + "\r\n";
    }
    return s;
}

BindingFlags.Public reflects only public members. If you want private member too, use also the BindingFlags.Private flag.
You may use the this.GetType().GetFields() at object initialization, to call it only once.

This works for framework 2 also.
Change it to your needs.

joe
  • 8,344
  • 9
  • 54
  • 80
0

So, here it is:

public class ABC
    {
        public int one;
        public string two;
        public int three;

        public override string ToString()
        {
            string names = String.Empty;
            System.Reflection.FieldInfo[] infos = this.GetType().GetFields();

            foreach (System.Reflection.MemberInfo inf in infos)
            {
                if (names == String.Empty)
                {
                    names = inf.Name;
                }
                else
                {
                    names += ';' + inf.Name;
                }
            }

            return names;
        }
    }

Enjoy!

0

Instead of using Reflection, you can use any of the following two approaches:

1: Here you can serialize your class object to a JSON object which would be more readable:

    public override string ToString()
    {

        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ABC));
        string str;
        using (MemoryStream stream = new MemoryStream())
        {
            serializer.WriteObject(stream, this);
            stream.Position = 0;
            using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8))
            {

                str = streamReader.ReadToEnd();
            }
        }

        return str;
}

2: Here you can serialize your class object to XML which can be utilize some where else:

    public override string ToString()
    {

        XmlSerializer s = new XmlSerializer(typeof(ABC));
        StringBuilder sb = new StringBuilder();
        var xtw = XmlTextWriter.Create(sb);
        s.Serialize
            (xtw, this);

        return sb.ToString();
}
Nitin Joshi
  • 1,638
  • 1
  • 14
  • 17
0

Finally Get solution to my problem :)

using System;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        MyClass mC= new MyClass();
        string result = mC.ToString();
    }
}

class MyClass
{
    string someValue = "One";
    int someValue1 = -1;
    bool someValue2 = false;
    float someValue3 = 2.2f;

    public string SomeValue
    {
        get{ return this.someValue;}
    }

    public int SomeValue1
    {
        get { return this.someValue1; }
    }

    public bool SomeValue2
    {
        get { return this.someValue2; }
    }

    public float SomeValue3
    {
        get { return this.someValue3; }
    }

    public override string ToString()
    {
        string result = string.Empty;
        Type type = this.GetType();
        PropertyInfo [] pInfo = type.GetProperties();

        for (int i = 0; i <= pInfo.Length-1; i++)
        {
            Type internalType = this.GetType();
            PropertyInfo pInfoObject = internalType.GetProperty(pInfo[i].Name);
            object value = pInfoObject.GetValue(this,null);
            result += pInfo[i].Name + " : " + value.ToString() + System.Environment.NewLine;
        }
        return result;
    }
}
AHMAD SUMRAIZ
  • 535
  • 8
  • 21
0

Here is an other solution if we use static fields and fieldsInfo:

    class ReflectionTest
{
    public static int Height = 2;
    public static int Width = 10;
    public static int Weight = 12;
    public static string Name = "Got It";

    public override string ToString()
    {
        string result = string.Empty;
        Type type = typeof(ReflectionTest); 
        FieldInfo[] fields = type.GetFields();
        foreach (var field in fields)
        {
            string name = field.Name; 
            object temp = field.GetValue(null);
            result += "Name:" + name + ":" + temp.ToString() + System.Environment.NewLine;
        }
        return result;
    }

}
AHMAD SUMRAIZ
  • 535
  • 8
  • 21