简体   繁体   English

C#如何获取类属性的名称(在字符串中)?

[英]C# how to get the name (in string) of a class property?

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 注意:System.Web.Mvc.SelectList

I do not like to have to write the property name with "Id" and "DisplayName". 我不喜欢用“Id”和“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? C#如何在字符串中获取属性名称?

UPDATE 1 更新1

With the help of Christian Hayter, I can use: 在Christian Hayter的帮助下,我可以使用:

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. 随意分享:)谢谢。

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. 请注意,由于您没有读取属性值,因此该类的任何实例都将执行此操作。

Since C# 6.0, you can now use 从C#6.0开始,您现在可以使用了

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

(Those aren't parameters btw, they're properties.) (那些不是参数btw,它们是属性。)

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

var name = (string) typeof(TimeZone).GetProperty("DisplayName").GetValue(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. 这将起作用,除非声明的id和displayname的顺序不会改变。 or else you can think of defining an attribute for the property to differentiate between id and displayname. 或者您可以考虑为属性定义属性以区分id和displayname。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM