2010-11-24 87 views
2
public class TimeZone 
{ 
    public int Id { get; set; } 
    public string DisplayName{ get; set; } 
} 

在一些其他類我有:C#如何獲取類屬性的名稱(字符串)?

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

注:System.Web.Mvc.SelectList

我不喜歡有與 「ID」 寫入屬性名稱和「DisplayName」。稍後,也許屬性名稱會改變,編譯器將不會檢測到此錯誤。 C#如何獲取字符串中的屬性名稱?

更新1

基督教艾泰的幫助下, 我可以使用:

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)); 

如果有人有其他的想法,而不需要創建的新對象。隨意分享:)謝謝。

回答

13

您可以創建一個實用的方法來從表達式目錄樹中提取的屬性名稱,像這樣:

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

然後你可以叫它像這樣:

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

請注意,該類的任何實例都會執行,因爲您沒有讀取屬性值,只有名稱。

+0

這是一個很好的解決方案,但請記住使用表達式樹的任何性能開銷以及更改所有引用時所需的重構量。它甚至可以忽略不計,但只有一種方法可以找到! – 2010-11-24 17:09:04

+1

我還沒有對此進行分析,但理論上代碼是從編譯器已經構建的表達式樹對象圖開始工作的,因此讀取名稱應該非常快。如果你想讀取表達式的*值*,那就完全不同了! – 2010-11-24 20:39:33

0

(這些都不是參數順便說一句,他們的屬性。)

嗯,一種選擇是使用委託。例如:

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

然後:

var gmtList = new SelectList<TimeZone>(repository.GetSystemTimeZones(), 
             tz => tz.Id, tz => tz.DisplayName); 
+0

不錯的選擇,但「System.Web.Mvc.SelectList」不能與類型參數一起使用。所以,我不能使用這個解決方案。無論如何,謝謝:) – asdas 2010-11-24 12:04:30

+1

@asdas:如果你說過哪種類型是開始的,那可能會有很大的幫助。你沒有給我們任何背景。 – 2010-11-24 12:10:43

0

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

0
string id=typeof(TimeZone).GetProperties()[0].Name; 
string displayName=typeof(TimeZone).GetProperties()[1].Name; 


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

這會工作,除非在該ID和顯示名稱聲明不更改順序。 或者你可以考慮爲屬性定義一個屬性來區分id和displayname。

0

由於C#6.0中,你現在可以使用

var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    nameof(TimeZone.Id), 
    nameof(TimeZone.DisplayName)); 
相關問題