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 に答える