请看一下这段代码:
public void BindElements<T>(IEnumerable<T> 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等......它必须是通用的!
如何获取真实属性表单项?只有反思?
答案 0 :(得分:7)
Oded is right,对他或我来说似乎没有任何意义尝试使这个方法通用。您正在尝试对其功能实际上特定于几种类型的方法进行泛化。
现在,就是说,该函数的 bulk 似乎与您要访问的此属性无关。那么为什么不将它分成两部分:可以通用化的部分,以及不能部署的部分:
这样的事情:
void BindElements<T, TProperty>(IEnumerable<T> dataObjects,
Func<T, TProperty> 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<IPerson> people)
{
BindElements(people, p => p.FirstName);
}
...然后是IOrder
:
public void BindOrders(IEnumerable<IOrder> orders)
{
BindElements(orders, o => p.OrderNumber);
}
......等等。
答案 1 :(得分:4)
如果向泛型类型添加constraint(比如必须实现IPerson
接口),则可以使用界面上定义的任何方法:
public void BindElements<T>(IEnumerable<T> dataObjects) where T : IPerson
如果IPerson
定义了FirstName
和LastName
个性能,您可以将它们与T
一起使用。
请参阅可能的generic constraints种不同类型的链接。
答案 2 :(得分:3)
根据Dan的回答,Func<T, TProperty> selector
只是说selector
是一个方法的标识符,该方法接受T
类型的参数并且返回类型为TProperty
。因此,可以作为第二个参数传递给BindElements
的有效方法是,例如,
string CreatePersonElement(IPerson person) {
return string.Format("{0} {1}", person.FirstName, person.LastName);
}
在这种情况下,TProperty
为string
,T
为IPerson
。然后,您可以像这样呼叫BindElements
BindElements(myPersonCollection,CreatePersonElement);
其中myPersonCollection可以是您所指的任何List<T>
。然后继续前进到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
的第二个参数,以支持您要支持的每种类型(例如ICustomer
,IOrder
)。
答案 3 :(得分:0)
我会阅读http://msdn.microsoft.com/en-us/library/d5x73970.aspx并再次考虑Oded的答案。