2
public class TimeZone
{
    public int Id { get; set; }
    public string DisplayName{ get; set; }
}

In some other class I've:

   var gmtList = new SelectList(
       repository.GetSystemTimeZones(), 
       "Id",
       "DisplayName");

Note: System.Web.Mvc.SelectList

I do not like to have to write the property name with "Id" and "DisplayName". Later in time, maybe the property name will change and the compiler will not detect this error. C# how to get property name in a string?

UPDATE 1

With the help of Christian Hayter, I can use:

var tz = new TimeZone();
var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    NameOf(() => tz.Id), 
    NameOf(() => tz.TranslatedName));

OR

var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    NameOf(() => new TimeZone().Id), 
    NameOf(() => new TimeZone().TranslatedName));

If someone has other idea without the need of creating a new object. Feel free to share it :) thank you.

asdas
  • 31
  • 1
  • 4

5 Answers5

13

You could create a utility method to extract the property name from an expression tree, like this:

string NameOf<T>(Expression<Func<T>> expr) {
    return ((MemberExpression) expr.Body).Member.Name;
}

Then you can call it like this:

var gmtList = new SelectList(repository.GetSystemTimeZones(),
    NameOf(() => tz.Id),
    NameOf(() => tz.DisplayName));

Note that any instance of the class will do, since you are not reading the property value, only the name.

Christian Hayter
  • 30,581
  • 6
  • 72
  • 99
  • This is a great solution, but keep in mind any performance overhead from using expression trees as well as the amount of refactoring necessary when it comes time to change all the references. It may even be negligible, but there's only one way to find out! – Mark Cidade Nov 24 '10 at 17:09
  • 1
    I haven't profiled this, but theoretically the code is working from an expression tree object graph that has already been constructed by the compiler, so it should be quite fast to read the name. If you want to read the *value* of the expression, that's quite a different matter! – Christian Hayter Nov 24 '10 at 20:39
  • Any performance testing done on this? Would it be wise to use it with MVVM INotifyPropertyChanged? – Stefan Vasiljevic Aug 22 '14 at 20:00
0

Since C# 6.0, you can now use

var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    nameof(TimeZone.Id),
    nameof(TimeZone.DisplayName));
Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
0

(Those aren't parameters btw, they're properties.)

Well, one option is to use delegates. For example:

public class SelectList<T>
{
    public SelectList(IEnumerable<T> source,
                      Func<T, string> idProjection,
                      Func<T, string> displayProjection)
    {
        ...
    }
}

Then:

var gmtList = new SelectList<TimeZone>(repository.GetSystemTimeZones(),
                                       tz => tz.Id, tz => tz.DisplayName);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Nice option but the 'System.Web.Mvc.SelectList' cannot be used with type arguments. So, I can't use this solution. Thanks anyway :) – asdas Nov 24 '10 at 12:04
  • 1
    @asdas: If you'd said which type it was to start with, that would have helped a great deal. You gave us no context whatsoever. – Jon Skeet Nov 24 '10 at 12:10
0

var name = (string) typeof(TimeZone).GetProperty("DisplayName").GetValue(0);

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
  • Once again you are writing the DisplayName withing Quotation marks. Not what I am looking for :) Thanks anyway. – asdas Nov 24 '10 at 12:02
  • You can replace it with a variable that gets its value from an external data source, silly : ) – Mark Cidade Nov 24 '10 at 17:06
0
string id=typeof(TimeZone).GetProperties()[0].Name;
string displayName=typeof(TimeZone).GetProperties()[1].Name;


var gmtList = new SelectList(
   repository.GetSystemTimeZones(), 
   id,
   displayName);

this will work, unless the order in which id and displayname declared doesn't change. or else you can think of defining an attribute for the property to differentiate between id and displayname.

Novice
  • 2,447
  • 3
  • 27
  • 33