【问题标题】:Use 'dynamic' throw a RuntimeBinderException使用“动态”抛出 RuntimeBinderException
【发布时间】:2013-01-23 03:21:51
【问题描述】:
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'会执行很多次,性能很差。我该如何解决这个问题。

【问题讨论】:

  • 你能把Animal上的NickName改成Name吗?
  • 如果你想要性能,使用带有属性NameBase接口并在PeploeAnimal实现它
  • @shf301 抱歉,我无法更改。

标签: .net c#-4.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);
                }
            }

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

【讨论】:

  • 谢谢,我可以通过你的代码得到我想要的。但是我的ItemSource非常大,我不知道for循环中的反射是否足够好。
  • 它会起作用,因为我只将它用于大型收藏。如果你愿意,你甚至可以让它并行和异步。如果获得更快的性能,还可以缓存。让我知道是否需要任何进一步的帮助。对于长列表,将 yeild 与 IEnumarable 结合使用会有所帮助。 PS。如果您的问题得到解决,请选择正确答案
猜你喜欢
  • 1970-01-01
  • 2013-02-07
  • 2014-09-27
  • 2015-01-30
  • 2013-08-26
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多