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'会多次执行,性能很差。如何解决这个问题。
答案 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);
}
}
此代码的工作方式与您想要的完全相同。它不依赖于你在课堂上的任何财产。如果需要进一步的细节,请告诉我。