从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
定义了FirstName
和LastName
peroperties,则可以将它们与T
一起使用。
请参阅链接,了解可能的不同类型的通用约束 。
添加到Dan的答案, Func
只是说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
。 然后继续前进到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
)。
我会阅读http://msdn.microsoft.com/en-us/library/d5x73970.aspx并再次考虑Oded的答案。
- 使用iTextSharp禁用扩展function
- LINQ和自然排序顺序
- TextFormatFlags枚举中EndEllipsis和WordEllipsis之间的区别是什么?
- 无法将LongListSelector.SelectedItem绑定到MVVM属性
- INotifyPropertyChange~当属性是一个集合并且一个新项目被添加到集合时,PropertyChanged不会触发
- .NET DateTime,与OADate进行转换时的分辨率是否不同?
- C#中的DataTable.Select和Performance问题
- 我可以检查格式说明符是否对给定的数据类型有效吗?
- 在C#SSL WebSocket客户端是.net 4.0吗?