Farhad-Taran
Farhad-Taran

Reputation: 6512

How to loop through properties of objects in c#?

I have a method which gets the values of the properties of an object and appends some commas to it. I want to make this generinc so i can use it with other objects.

            foreach (var row in rows.ToList())
            {
                sbResult.Append(
                    delimiter + row.MediaName + delimiter + separator +
                    delimiter + row.CountryName + delimiter + separator +
                    delimiter + row.ItemOverRideDate + delimiter + separator +
                    delimiter + row.Rating + delimiter + separator +
                    delimiter + row.BatchNo + delimiter + separator +
                    delimiter + row.NoInBatch + delimiter + separator +
                    delimiter + row.BatchDate + delimiter + separator +
                    delimiter + row.DataType + delimiter + separator +
                    delimiter + row.ByLine + delimiter + separator +
                    delimiter + row.IssueNo + delimiter + separator +
                    delimiter + row.Issue + delimiter + separator +
                    delimiter + row.MessageNo + delimiter + separator +
                    delimiter + row.Message + delimiter + separator +
                    delimiter + row.SourceName + delimiter + separator +
                    delimiter + row.SourceType + delimiter + separator);

                //end of each row
                sbResult.AppendLine();
            }

I have tried using var rowData = row.GetType().GetProperties(); but it only returns the property itself and I dont know how to get the value of the property.

Upvotes: 1

Views: 1401

Answers (5)

ken2k
ken2k

Reputation: 48975

var values = instance
    .GetType()
    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Select(z => string.Format("{0}: {1}\n", z.Name, z.GetValue(instance, null)));

string res = string.Concat(values);

Where instance is the instance of your object. You might want to avoid LINQ and use a loop if StringBuilder is required (depending on the number of properties).

Upvotes: 0

Jon
Jon

Reputation: 437336

Since Type.GetProperties returns a collection of PropertyInfo, you follow that up by calling PropertyInfo.GetValue. Here's how you can do that (and all the rest together) with LINQ:

var line = string.Join(
             row.GetType().GetProperties()
              .Select(pi => pi.GetValue(row))
              .Select(v => delimiter + v.ToString() + delimiter),
             separator);

However, you might want to reconsider your approach. This code will break if GetProperties fetches static properties or indexers along with "normal" properties; it also requires that the code be run with full trust (otherwise no reflection is possible). And finally, it's going to be slow because a) reflection is inherently slow and b) it will keep reflecting on the same things over and over again without caching any of the information it has already discovered.

In addition to the above potential problems, if there is even a remote chance that you will later want to filter what gets printed out it is probably better to encapsulate this logic inside a (virtual?) method on row and just do something like

sbResult.AppendLine(row.SerializeAsLine());

Upvotes: 2

Hossein Narimani Rad
Hossein Narimani Rad

Reputation: 32481

GetProperties returns an array of PropertyInfo, so use the GetValue method and use your object as it's input to get the value for each property. Here is the code:

public class MyClass
{
    public string MyProperty1 { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
}

Then

MyClass myObj = new MyClass() { MyProperty1 = "first", MyProperty2 = "second", MyProperty3 = "third" };

List<string> array = new List<string>();

foreach (var item in typeof(MyClass).GetProperties())
{
    array.Add(item.GetValue(myObj, null).ToString());
}

var result = string.Join(",", array); //use your own delimiter 

Upvotes: 0

Murugan
Murugan

Reputation: 1451

Here it is.

List<PropertyInfo> _propInfo = _row.GetType().GetProperties();

    foreach (var item in _propInfo)
    {
    object _value = item.GetValue(_row, null);
    if (_value != null)
    {
    // Save the Value
    }
    }

Upvotes: 0

Matthew Watson
Matthew Watson

Reputation: 109547

You can use something like this to iterate over all the properties of a particular type:

public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object obj)
{
    return from p in obj.GetType().GetProperties()
            where p.PropertyType == typeof(T)
            select new KeyValuePair<string, T>(p.Name, (T)p.GetValue(obj));
}

Then you could specify the type as string for all your string properties.

Compilable sample:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        private static void Main()
        {
            var test = new Test
            {
                Str1 = "S1",
                Str2 = "S2",
                Str3 = "S3",
                Str4 = "S4"
            };

            foreach (var property in PropertiesOfType<string>(test))
            {
                Console.WriteLine(property.Key + ": " + property.Value);
            }
        }

        public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object obj)
        {
            return from p in obj.GetType().GetProperties()
                    where p.PropertyType == typeof(T)
                    select new KeyValuePair<string, T>(p.Name, (T)p.GetValue(obj));
        }
    }

    public class Test
    {
        public string Str1 { get; set; }
        public string Str2 { get; set; }
        public string Str3 { get; set; }
        public string Str4 { get; set; }
    }
}

Upvotes: 0

Related Questions