0
public class Peploe
{
    public string Name { get; set; }
}

public class Animal
{
    public string NickName { get; set; }
}

internal static class Program
{
    /// <summary>
    /// This 'ItemSorce' will be assignment by anywhere , so i don't know it have 'Name' property.
    /// </summary>
    public static IEnumerable ItemSource { get; set; }

    private static void Main()
    {
        var list = new List<Peploe>() {new Peploe() {Name = "Pato"}};
        ItemSource = list;

        //Test2
        //var animals = new List<Animal>() { new Animal() { NickName = "Pi" } };
        //ItemSource = animals;

        dynamic dy;
        foreach (var item in ItemSource)
        {
            dy = item;
            Console.WriteLine(dy.Name);//If I Uncomment 'Test2',it will throw a RuntimeBinderException at here.
        }
    }
}

If I use reflection,it can resolve this problem. But when 'ItemSource' is very huge, the 'foreach' will excute many times,the performance is bad.How can I resolve this problem.

Scarface
  • 89
  • 5

1 Answers1

1

You need to add little bit of reflection to make is complete dynamic. And trust me that will not hurt performance as I am already using it. Here is code sample I have created from you sample. It is still not production ready but you will get the basic idea how you can do it, with all your restriction.

dynamic dy;
            List<dynamic> result = new List<dynamic>(); 

            foreach (var item in ItemSource)
            {
                dy = new ExpandoObject();
                var d = dy as IDictionary<string, object>;

                foreach (var property in item.GetType().GetProperties())
                {
                    d.Add(property.Name, item.GetType().GetProperty(property.Name).GetValue(item, null));
                }

                result.Add(dy);
            }

            foreach (var item in result)
            {
                var r = ((dynamic)item) as IDictionary<string, object>;
                foreach (var k in r.Keys)
                {
                    Console.WriteLine(r[k] as string);
                }
            }

This code works exactly way you want. Its not depended on whatever property you have in class. Please let me know if any further details needed.

kunjee
  • 2,739
  • 1
  • 23
  • 38
  • Thanks,I can get what I want by your code.But my `ItemSource` is very huge,i don't know the reflection in the for loop is good enough. – Scarface Jan 25 '13 at 01:38
  • It will work, as I am using it for large collection only. And even for more you can make it parallel and async if you want. And also cache if for faster performance. Let me know if any further help needed. For long list use yeild with IEnumarable that will help. PS. Please select as correct answer if your problem is solved – kunjee Jan 25 '13 at 07:29