从C#中的通用对象获取属性

请看一下这段代码:

public void BindElements(IEnumerable dataObjects) { Paragraph para = new Paragraph(); foreach (T item in dataObjects) { InlineUIContainer uiContainer = this.CreateElementContainer(item.FirstName ????? ) para.Inlines.Add(uiContainer); } FlowDocument flowDoc = new FlowDocument(para); this.Document = flowDoc; } 

在Visual Studio“item.XXX”中编写时,我应该从我的权限中获取属性,如.FirstName或.LastName。 我不知道数据对象是IEnumerable还是IOrder等……它必须是通用的!

如何获得真实属性表单项? 只有反思?

Oded是对的 ,似乎(对他或我来说)没有任何意义来尝试使这种方法通用。 您正在尝试对其function实际上特定于几种类型的方法进行泛化。

现在,也就是说,似乎该函数的大部分与您想要访问的此属性无关。 那么为什么不将它分成两部分:可以泛化的部分,以及不能部署的部分:

像这样的东西:

 void BindElements(IEnumerable dataObjects, Func selector) { Paragraph para = new Paragraph(); foreach (T item in dataObjects) { // Notice: by delegating the only type-specific aspect of this method // (the property) to (fittingly enough) a delegate, we are able to // package MOST of the code in a reusable form. var property = selector(item); InlineUIContainer uiContainer = this.CreateElementContainer(property) para.Inlines.Add(uiContainer); } FlowDocument flowDoc = new FlowDocument(para); this.Document = flowDoc; } 

然后你处理特定类型的重载,例如IPerson ,可以重用这段代码(我怀疑这可能是你所有沿着代码重用的原因):

 public void BindPeople(IEnumerable people) { BindElements(people, p => p.FirstName); } 

……然后是IOrder

 public void BindOrders(IEnumerable orders) { BindElements(orders, o => p.OrderNumber); } 

…等等。

如果向generics类型添加约束 (假设它必须实现IPerson接口),则可以使用接口上定义的任何方法:

 public void BindElements(IEnumerable dataObjects) where T : IPerson 

如果IPerson定义了FirstNameLastName peroperties,则可以将它们与T一起使用。

请参阅链接,了解可能的不同类型的通用约束 。

添加到Dan的答案, Func selector只是说selector是一个方法的标识符,该方法接受类型为T的参数并且返回类型为TProperty 。 因此,可以作为第二个参数传递给BindElements的有效方法是,例如,

 string CreatePersonElement(IPerson person) { return string.Format("{0} {1}", person.FirstName, person.LastName); } 

在这种情况下, TProperty将是一个stringT将是IPerson 。 然后你可以像这样调用BindElements

 BindElements(myPersonCollection,CreatePersonElement); 

其中myPersonCollection可以是你所指的List 。 然后继续前进到foreach循环

 foreach (T item in dataObjects) { // Notice: by delegating the only type-specific aspect of this method // (the property) to (fittingly enough) a delegate, we are able to // package MOST of the code in a reusable form. var property = selector(item); InlineUIContainer uiContainer = this.CreateElementContainer(property) para.Inlines.Add(uiContainer); } 

property被设置为TProperty类型的对象,在CreatePersonElement的情况下是一个string 。 如果string不适合您,只需将方法的返回类型更改为CreateElementContainer接受的任何参数。

然后,您可以将这些方法之一传递给您要支持的每种类型的BindElements的第二个参数(即ICustomerIOrder )。

我会阅读http://msdn.microsoft.com/en-us/library/d5x73970.aspx并再次考虑Oded的答案。