none
C# class issue RRS feed

  • Question

  • Dear All,

    I have a class like this

    class Person
    {
        public int Age { get; set; }
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string Designation { get; set; }
      
    }
    
    Person objP= new Person();
    objP.Age=15;
    objP.FirstName="Victor";
    objP.SecondName="James";
    objP.Designation="Manager";

    From this class I want to generate 2 comma separated lists

    Age,FirstName,SecondName,Designation
    Age=15,FirstName=Victor,SecondName=James,Designation=Manager

    Also I don't need to specify all 4 properties all the time. I mean I can do this also

    Person objP= new Person();
    objP.Age=15;
    objP.FirstName="Victor";

    So now it will give me these 2 lists

    Age,FirstName
    Age=15,FirstName=Victor


    Please help!

    Monday, November 25, 2019 3:51 AM

Answers

  • Thanks for your reply. Instead of having 2 separate functions like NamesOnly and NameValueOnly can we have a single function function that can do both. I am thinking of using a single function that returns 2 CSV value strings.

    Of course you can.

    Here the method second parameter determines if names + value or just names. Here a CheckBox Checked state determines what to do.

    using System.Collections.Generic;
    
    namespace WindowsFormsApp1
    {
        public class Dumper
        {
            public string NamesAndValues<T>(T sender, bool values = true)
            {
                var data = new List<string>();
    
                var piList = sender.GetType().GetProperties();
    
                foreach (var pi in piList)
                {
                    var value = pi.GetValue(sender);
                    if (pi.GetValue(sender) != null)
                    {
                        if (values)
                        {
                            data.Add(pi.Name + "=" + value);
                        }
                        else
                        {
                            data.Add(pi.Name);
                        }
                    }
                }
    
                return string.Join(",", data.ToArray());
            }
        }
    }
    

    Sample usage

    var person1 = new Person
    {
        Age = 1,
        FirstName = "Karen",
        LastName = "Payne",
        Designation = "Owner"
    };
    var person2 = new Person
    {
        Age = 2,
        FirstName = "Jane",
        LastName = "Adams",
        Designation = "Manager"
    };
    
    var peopleList = new List<Person> { person1, person2 };
    
    
    var dump = new Dumper();
    foreach (var person in peopleList)
    {
        // uses a CheckBox to determine if the names and values or names only should
        // be outputted.
        Console.WriteLine(dump.NamesAndValues(person, checkBox1.Checked));
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Sammy Williams Monday, November 25, 2019 6:42 PM
    Monday, November 25, 2019 6:00 PM
    Moderator

All replies

  •             Person objP = new Person();
                objP.Age = 15;
                objP.FirstName = "Victor";
                objP.SecondName = "James";
                objP.Designation = "Manager";
    
                PropertyInfo[] piList = objP.GetType().GetProperties();
                List<string> vList = new List<string>();
                List<string> pList = new List<string>();
                foreach(PropertyInfo pi in piList)
                {
                    object o = pi.GetValue(objP);
                    if (pi.GetValue(objP) != null) 
                    {
                        pList.Add(pi.Name);
                        vList.Add(pi.Name + "=" + o);
                    }
                }

    IT IS CALLED REFLECTION.. TAKE YOUR TIME AND READ ABOUT IT..


    "I = I + 1" .. Isn't it boolshit?


    Monday, November 25, 2019 4:18 AM
  • If you want to only do that for Person class, then adding method what constructs string might be the simplest and most efficient option.

    public class Person
    {
        public int Age { get; set; } = -1;
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string Designation { get; set; }
    
        public string ToCommaSeparatedString(bool appendPropertyNames)
        {
            List<string> values = new List<string>(4);
    
            const string propertyNameValueFormat = "{0}={1}";
    
            if (Age >= 0)
                values.Add(appendPropertyNames ? string.Format(propertyNameValueFormat, nameof(Age), Age) : Age.ToString());
    
            if (FirstName != null)
                values.Add(appendPropertyNames ? string.Format(propertyNameValueFormat, nameof(FirstName), FirstName) : FirstName);
    
            if (SecondName != null)
                values.Add(appendPropertyNames ? string.Format(propertyNameValueFormat, nameof(SecondName), SecondName) : SecondName);
    
            if (Designation != null)
                values.Add(appendPropertyNames ? string.Format(propertyNameValueFormat, nameof(Designation), Designation) : Designation);
    
            return string.Join(",", values);
        }
    }

    But if you have same requirement for multiple classes, then more general approach using reflection, like in sample from RobbKirk, is easier to implement.

    Monday, November 25, 2019 5:39 AM
  • Yes my requirement is for only Person class. Ideally in the person class I want 1 method that returns a comma separated list of propertynames and second method that returns a comma separated list of propertynames with values
    Monday, November 25, 2019 12:25 PM
  • Hello,

    You might consider a generic method. And note LastName is SecondName, I did a auto rename in my head but sinc this below used generics it does not matter.

    Change the namespace to your namespace

    using System.Collections.Generic;
    
    namespace WindowsFormsApp1
    {
        public class Dumper
        {
            /// <summary>
            /// Return a comma delimited string with all properties and values
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sender"></param>
            /// <returns></returns>
            public string NamesAndValues<T>(T sender)
            {
                var data = new List<string>();
    
                var piList = sender.GetType().GetProperties();
    
                foreach (var pi in piList)
                {
                    var value = pi.GetValue(sender);
                    if (pi.GetValue(sender) != null)
                    {
                        data.Add(pi.Name + "=" + value);
                    }
                }
    
                return string.Join(",", data.ToArray());
            }
            /// <summary>
            /// Return a comma delimited string or property names
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sender"></param>
            /// <returns></returns>
            public string NamesOnly<T>(T sender)
            {
                var data = new List<string>();
    
                var piList = sender.GetType().GetProperties();
    
                foreach (var pi in piList)
                {
                    var value = pi.GetValue(sender);
                    if (pi.GetValue(sender) != null)
                    {
                        data.Add(pi.Name);
                    }
                }
    
                return string.Join(",", data.ToArray());
            }
        }
    }
    

    Usage to get property names and their values. Instead of displaying in a console write line you could append them to say a StringBuilder and in turn if pushing to a text file use .ToString of the StringBuilder to write to a file.

    private void button1_Click(object sender, EventArgs e)
    {
        var person1 = new Person
        {
            Age = 1,
            FirstName = "Karen",
            LastName = "Payne",
            Designation = "Owner"
        };
        var person2 = new Person
        {
            Age = 2,
            FirstName = "Jane",
            LastName = "Adams",
            Designation = "Manager"
        };
        
        var peopleList = new List<Person> { person1, person2 };
    
    
        var dump = new Dumper();
        foreach (var person in peopleList)
        {
    
            Console.WriteLine(dump.NamesAndValues(person));
        }
    
    }

    Results

    Age=1,FirstName=Karen,LastName=Payne,Designation=Owner
    Age=2,FirstName=Jane,LastName=Adams,Designation=Manager

    For only names

    var person1 = new Person
    {
        Age = 1,
        FirstName = "Karen",
        LastName = "Payne",
        Designation = "Owner"
    };
    var person2 = new Person
    {
        Age = 2,
        FirstName = "Jane",
        LastName = "Adams",
        Designation = "Manager"
    };
    
    var peopleList = new List<Person> { person1, person2 };
    
    var dump = new Dumper();
    foreach (var person in peopleList)
    {
        Console.WriteLine(dump.NamesOnly(person));
    
    }

    Results

    Age,FirstName,LastName,Designation
    Age,FirstName,LastName,Designation


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, November 25, 2019 3:09 PM
    Moderator
  • Thanks for your reply. Instead of having 2 separate functions like NamesOnly and NameValueOnly can we have a single function function that can do both. I am thinking of using a single function that returns 2 CSV value strings.
    Monday, November 25, 2019 4:50 PM
  • Thanks for your reply. Instead of having 2 separate functions like NamesOnly and NameValueOnly can we have a single function function that can do both. I am thinking of using a single function that returns 2 CSV value strings.

    Of course you can.

    Here the method second parameter determines if names + value or just names. Here a CheckBox Checked state determines what to do.

    using System.Collections.Generic;
    
    namespace WindowsFormsApp1
    {
        public class Dumper
        {
            public string NamesAndValues<T>(T sender, bool values = true)
            {
                var data = new List<string>();
    
                var piList = sender.GetType().GetProperties();
    
                foreach (var pi in piList)
                {
                    var value = pi.GetValue(sender);
                    if (pi.GetValue(sender) != null)
                    {
                        if (values)
                        {
                            data.Add(pi.Name + "=" + value);
                        }
                        else
                        {
                            data.Add(pi.Name);
                        }
                    }
                }
    
                return string.Join(",", data.ToArray());
            }
        }
    }
    

    Sample usage

    var person1 = new Person
    {
        Age = 1,
        FirstName = "Karen",
        LastName = "Payne",
        Designation = "Owner"
    };
    var person2 = new Person
    {
        Age = 2,
        FirstName = "Jane",
        LastName = "Adams",
        Designation = "Manager"
    };
    
    var peopleList = new List<Person> { person1, person2 };
    
    
    var dump = new Dumper();
    foreach (var person in peopleList)
    {
        // uses a CheckBox to determine if the names and values or names only should
        // be outputted.
        Console.WriteLine(dump.NamesAndValues(person, checkBox1.Checked));
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Sammy Williams Monday, November 25, 2019 6:42 PM
    Monday, November 25, 2019 6:00 PM
    Moderator