Cornwell
Cornwell

Reputation: 3410

Understanding how c# properties work

Why does this work:

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

And this doesn't:

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

Shouldn't it be the same?

Upvotes: 1

Views: 128

Answers (2)

p.s.w.g
p.s.w.g

Reputation: 149060

No, GetProperty("username") returns the PropertyInfo associated with with the username property. This should be the same object for all values in your collection (assuming they are the same type). To get the value of this property for each object you'd have to call GetValue and pass in an instance of the object whose property value you'd like to return, like this:

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

Note the use of implicit typing with the var keyword for brevity.

However, I really wouldn't do this unless you really have to; using reflection is slow compared to direct property access.

Also note, if you're trying to run this against a Linq-to-Entities provider or similar, this simply won't work. That's because the Linq provider needs to translate the expression you provide to a SQL query, and GetType, GetProperty, and GetValue simply don't have a SQL equivalent (at least not one that the Linq provider can use).


Also note, in your example, username is actually a field rather than a property. In that case, you'd use GetField("username") instead (which returns a FieldInfo):

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

Alternatively, you could simply use dynamic, which will allow you to write something that looks like a normal property / field access, but will in fact cause the compiler to emit reflection code similar to what's described above:

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

Upvotes: 2

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

When you call GetType().GetProperty() it returns something called PropertyInfo. It is not same as the property value. As the name suggests, it can be expanded as "Property Information".

So it returns a object which tells you many useful information about the Property like What is the type of the property, Whether it has getter/setter, Which class it lives in and so forth.

Since PropertyInfo object just gives the general information about the property it can't be the value of your property, To get your property value you need to call PropertyInfo.GetValue method.

So equivalent code for reading the property value would be:

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

Upvotes: 2

Related Questions