4

I have a question very similiar to another question: Get name of property as a string.

His solution ended up with

// Static Property 
string name = GetPropertyName(() => SomeClass.SomeProperty); 

// Instance Property 
string name = GetPropertyName(() => someObject.SomeProperty); 

What I'd like is to have syntax similar to the Static Property but for an instance property.

The reason is that I have code now that uses reflection to get the value of a property for all objects within a collection, but i have to pass that in as a hardcoded string.

Example code:

double Sum = AmountCollection.Sum("thatfield");  

Well, this works great, but if "thatfield" was ever renamed, the code would no longer work. The compiler cant check for that since it's just a string. Also, Get References won't work either for the same reason.

So, is there a way to achieve the goal of getting a property name easily, (ie; just a function call), from an instance property?

Thanks.

Community
  • 1
  • 1
David
  • 43
  • 3

2 Answers2

6

Try this:

string name = GetPropertyName(() => default(SomeClass).SomeInstanceProperty);

You may get a compiler warning about "always causing a System.NullReferenceException", but that's not actually happening, since you don't execute the expression, which means that you can safely discard this warning. If you want to get rid of it, either disable it via pragma or just move the default() call into a function like this:

public static T Dummy<T>() {
  return default(T);
}

string name = GetPropertyName(() => Dummy<SomeClass>().SomeInstanceProperty);
Lucero
  • 59,176
  • 9
  • 122
  • 152
  • oh, I like that. It does work, just tested it out. I'm still creating an object, but it's much cleaner indeed. Thanks. – David Jun 26 '10 at 16:09
  • @David, no, you're NOT creating an object. `default()` is `null` for all reference types, and an empty value for value types (no constructor is being called, no heap memory is being allocated). – Lucero Jun 26 '10 at 16:14
  • @ChrisF, as I wrote, this warning is correct if the expression was ever executed. However, it is only used to extract metadata, so that this is not happening. – Lucero Jun 26 '10 at 16:15
  • Now, the solution from the other question required the Lambda expression and that extra function, is it possible to do something that looks kinda like: string NameOfProperty = typeof(default(AccountEntity).Email).Name; This code doesnt work, but something similar? – David Jun 26 '10 at 16:16
  • I misspoke about creating an object, didnt mean that exactly, more like it's doing additional work related to the object. But, in either case, it does work well and is clean, but see my last post? – David Jun 26 '10 at 16:17
  • @David, you have make the compiler build an `Expression` instance in order to retrieve the metadata of the expression. Therefore there is currently no other way than to go through a lambda expression. Don't worry about the "extra work" however, the overhead is minimal (since this is the same technique as used for all the LINQ stuff, which gets done pretty efficiently by the compiler). – Lucero Jun 26 '10 at 16:18
  • ok, thanks for the info. Part of it is just limiting the actual text that needs to be written to perform what I want. But your solution works, and I'm quite content with that. – David Jun 26 '10 at 16:21
0

With C# 6.0 you use nameof :

 nameof(SomeProperty)

This expression is resolved at compile-time to "SomeProperty".

Sprotty
  • 5,676
  • 3
  • 33
  • 52