从一个普通的对象获取属性在C#
这个代码看看请:从一个普通的对象获取属性在C#
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”我应该得到我的entitiy像.FirstName或属性。姓。我不知道数据对象是IEnumerable还是IOrder等......它必须是通用的!
我怎样才能得到真正的属性表单项?只有反思?
Oded is right,它似乎(对他或我)没有任何意义,试图使此方法通用。您正试图将其功能实际上特定于某些类型的方法泛化。
现在,那说,看起来批量的功能是独立于你想访问的这个属性。那么,为什么不把它拆分成两个部分:即可以泛型化,而哪些不能:
事情是这样的:
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);
}
...等等。
如果添加一个constraint的泛型类型(说它实现IPerson
接口),您可以使用该接口上定义的任何方法:
public void BindElements<T>(IEnumerable<T> dataObjects) where T : IPerson
如果IPerson
定义FirstName
和LastName
peroperties,你可以用它们与T
。
请参阅generic constraints不同类型的链接。
添加到丹的回答,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
)。
为什么**必须是通用的? – Oded 2010-11-27 17:25:28
我认为它比公共无效BindElements(对象数据对象)更好,因为我必须做演员... – Elisabeth 2010-11-27 17:49:31