了解c#属性的工作原理

时间:2014-08-13 19:37:46

标签: c#

为什么这样做:

foreach (KeyValuePair<Main_key, Main_data> entry in mainTable.OrderBy(key=> key.Value.username)
{
    ...
}

这并不是:

foreach (KeyValuePair<Main_key, Main_data> entry in mainTable.OrderBy(key=> key.Value.GetType().GetProperty("username"))
{
    ...
}

不应该一样吗?

2 个答案:

答案 0 :(得分:2)

不,GetProperty("username")会返回与username属性相关联的PropertyInfo。这应该是集合中所有值的相同对象(假设它们是相同的类型)。要获取每个对象的此属性的值,您必须调用GetValue并传入您想要返回其属性值的对象的实例,如下所示:

foreach (var entry in mainTable.OrderBy(key => key.Value.GetType().GetProperty("username").GetValue(key.Value, null))
{
    ...
}

请注意使用var keyword进行隐式输入以简化。

然而,除非你真的必须这样做,否则我真的不会这样做;与直接属性访问相比,使用反射速度较慢。

另请注意,如果您尝试针对Linq-to-Entities提供商或类似提供商运行此操作,则这根本不会起作用。这是因为Linq提供程序需要将您提供的表达式转换为SQL查询,而GetTypeGetPropertyGetValue根本没有SQL等价物(至少不是Linq提供商可以使用的那个)。


另请注意,在您的示例中,username实际上是字段而不是属性。在这种情况下,您可以改为使用GetField("username")(返回FieldInfo):

foreach (var entry in mainTable.OrderBy(key => key.Value.GetType().GetField("username").GetValue(key.Value))
{
    ...
}

或者,您可以简单地使用dynamic,这将允许您像正常属性/字段访问一样编写外观的内容,但实际上会导致编译器发出反射代码类似于上面描述的内容:

foreach (var entry in mainTable.OrderBy(key => ((dynamic)key.Value).username)
{
    ...
}

答案 1 :(得分:2)

当您致电GetType().GetProperty()时,会返回名为PropertyInfo的内容。它与属性值不同。顾名思义,它可以扩展为&#34;属性信息&#34;。

所以它返回一个对象,告诉你许多关于属性的有用信息,如属性的类型是否有getter / setter 它所在的课程等等。

由于PropertyInfo对象只提供有关该属性的一般信息,因此它可以是您的属性的值。要获取属性值,您需要调用PropertyInfo.GetValue方法。

因此,读取属性值的等效代码将是:

type.GetProperty("YourPropertyName").GetValue(yourInstance, null);