C# 从C中的泛型对象获取属性#
请查看此代码:C# 从C中的泛型对象获取属性#,c#,object,get,properties,generics,C#,Object,Get,Properties,Generics,请查看此代码: public void BindElements<T>(IEnumerable<T> dataObjects) { Paragraph para = new Paragraph(); foreach (T item in dataObjects) { InlineUIContainer uiContainer = this.CreateElementContainer(item.FirstN
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;
}
public void BindElements(IEnumerable数据对象)
{
段落段落=新段落();
foreach(数据对象中的T项)
{
InlineUIContainer-uiContainer=
此.CreateElementContainer(item.FirstName?????)
段落Inlines.Add(uiContainer);
}
FlowDocument flowDoc=新的FlowDocument(段落);
此.Document=flowDoc;
}
在Visual Studio中编写“item.XXX”时,我应该从我的实体获取属性,如.FirstName或.LastName。我不知道dataObjects是IEnumerable还是IOrder等等。。。它必须是通用的
如何获取“真实属性”表单项?仅使用反射?如果您向泛型类型中添加了一个(比如它必须实现IPerson
接口),则可以使用接口上定义的任何方法:
public void BindElements<T>(IEnumerable<T> dataObjects) where T : IPerson
public void BindElements(IEnumerable数据对象),其中T:IPerson
如果IPerson
定义了FirstName
和LastName
属性,则可以将它们与T
一起使用
查看不同类型的可能方法的链接。我会再次阅读并思考Oded的答案。,尝试将此方法通用化(对他或我而言)似乎没有任何意义。您正在尝试泛化一个方法,该方法的功能实际上特定于一些类型
这就是说,函数的大部分似乎独立于您想要访问的属性。那么,为什么不将其分为两部分:可以泛化的部分和不能泛化的部分:
大概是这样的:
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;
}
…然后对于IOrder
:
public void BindOrders(IEnumerable<IOrder> orders)
{
BindElements(orders, o => p.OrderNumber);
}
公共订单(IEnumerable订单)
{
BindElements(订单,o=>p.OrderNumber);
}
…等等。除了Dan的答案之外,
Func selector
只是说selector
是一个方法的标识符,该方法接受类型为T
的参数,返回类型为TProperty
。因此,可以作为第二个参数传递到BindElements
的有效方法是
string CreatePersonElement(IPerson person) {
return string.Format("{0} {1}", person.FirstName, person.LastName);
}
在这种情况下,T属性
将是一个字符串
,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
的情况下,它是一个字符串。如果字符串
不适用于您,只需将方法的返回类型更改为CreateElementContainer
接受作为其参数的内容即可
然后,您可以使用这些方法中的一种,为要支持的每种类型(即iccustomer
,IOrder
)的BindElements
传递第二个参数。请告诉我。我的答案几乎是一样的。@Oded很抱歉混淆了它不应该意味着…是一个IEnumerable它应该意味着ICustomer或IOrder等。。。但你几乎已经得到了。。。问题是我不能把IPerson放在那里,因为那样会破坏该方法的通用功能!公开public BindElements方法的UserControl的用户正在传递一个列表,或者IEnumerable,T可以是IPerson、ICCustomer或IOrder,你明白了吗?@Lisa-但是如果想要有特定的方法来调用你的泛型参数,你已经“破坏”了函数的泛型性质。请解释为什么几个重载不能比一个bastardized泛型函数更好地工作?@Oded她的bastardized泛型函数无论如何都不能工作,如果不同的实体没有FirstName属性,反射与否。@siride-很清楚这一点。这就是为什么我首先质疑通用方法。我认为它比public void BindElements(object dataObjects)好,因为我必须进行强制转换…啊,我想我已经对此发表了评论,我现在这样做了…:@Dan Tao=>如果我想传递两个“选择器”,比如FirstName和LastName,该怎么办,BindElements方法参数将如何更改?我从来没有读过这个TProperty+选择器,也没有真正理解它;-)刚刚开始做真正通用的东西。+1-肯定是一个很好的实现,我在想,Func可能是她元素容器创建的某种工厂方法。不是按位解决方案,但值得一提:P感谢示例!不客气-是的,丹的解决方案确实值得称赞=)
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);
}