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.
        }
    }
}

如果我使用反射,它可以解决这个问题。但是当'ItemSource'非常大时,'foreach'会执行很多次,性能很差。我该如何解决这个问题。

4

1 回答 1

1

您需要添加一点点反射以使其完全动态。相信我不会影响性能,因为我已经在使用它了。这是我从您的示例中创建的代码示例。它还没有准备好生产,但你会得到基本的想法,你可以如何做到这一点,并受到你的所有限制。

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);
                }
            }

这段代码完全按照你想要的方式工作。它不取决于您在课堂上拥有的任何财产。如果需要任何进一步的细节,请告诉我。

于 2013-01-24T06:59:32.607 回答