2010-11-24 90 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)); 
相关问题