使用'dynamic'抛出RuntimeBinderException

时间:2013-01-23 03:21:52

标签: .net c#-4.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'会多次执行,性能很差。如何解决这个问题。

1 个答案:

答案 0 :(得分: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);
                }
            }

此代码的工作方式与您想要的完全相同。它不依赖于你在课堂上的任何财产。如果需要进一步的细节,请告诉我。