C# 访问对象属性的索引器风格

9
有没有任何工具或库可以让我以索引器的方式访问我的对象属性?
public class User
{
    public string Name {get;set;}
}

User user = new User();
user.Name = "John";

string name = user["Name"];

也许动态关键字可以帮我解决这个问题?

我正在尝试构建一种通用的方法来做报告。 - user256034
6个回答

10

你可以使用反射通过属性名称获取属性值

   PropertyInfo info = user.GetType().GetProperty("Name");
   string name = (string)info.GetValue(user, null);

如果你想使用索引来实现这个功能,可以尝试类似以下的代码:

    public object this[string key]
    {
        get
        {
             PropertyInfo info = this.GetType().GetProperty(key);
             if(info == null)
                return null
             return info.GetValue(this, null);
        }
        set
        {
             PropertyInfo info = this.GetType().GetProperty(key);
             if(info != null)
                info.SetValue(this,value,null);
        }
    }

1
@user256034 非常有用。但是在运行时查找属性非常慢。唯一能够快速完成的方法是使用我的实现。 - Oskar Kjellin
不如使用动态语言。动态语言基本上是在运行时根据需要进行编译的。 - Ben Robinson
刚刚测试了 - 执行 string name = (string)user["Name"]; 的时间为 00:00:00.0005115 - Stecya
1
Dynamic在底层使用反射,但它还使用了一些智能缓存,因此性能应该比反射更好。 - Martin Fabik
我认为 Dynamic 在底层并没有使用反射技术。Dynamic需要DLR(Dynamic Language Runtime),如果它只使用反射技术是不需要DLR的。编译器将动态操作推迟,当在运行时遇到它们时,DLR会启动并对其进行评估。 - Ben Robinson
1
请查看这个测试应用程序 - http://geekswithblogs.net/SunnyCoder/archive/2009/06/26/c-4.0-dynamics-vs.-reflection.aspx。动态方法比反射更快。 - Stecya

3

查看这篇文章,它与索引器相关。字典存储所有的键和值,而不是使用属性。这样你就可以在运行时添加新的属性而不会失去性能。

public class User
{
    Dictionary<string, string> Values = new Dictionary<string, string>();
    public string this[string key]
        {
            get
            {
                return Values[key];
            }
            set
            {
                Values[key] = value;
            }
        }
}

有很多对象,因此对每个对象进行实现不是一个选项。 - user256034
@user256034,您只需要执行一次并将值存储在字典中而不是属性中。 - Oskar Kjellin

2
你肯定可以继承DynamicObject并以这种方式实现。

http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetindex.aspx

使用其他人在此处提到的简单索引器方法将限制您要么仅返回“object”(并且必须进行强制转换),要么在类中仅具有字符串类型。 编辑:如其他地方所述,即使使用动态类型,您仍然需要使用反射或某种查找形式来检索TryGetIndex函数内部的值。

@user256034 上面的链接有一个不错的例子。 - Andrew Hanlon

1

在类实现索引器之前,您无法这样做。


1

如果您只想根据字符串值访问属性,可以使用反射来实现类似的功能:

string name = typeof(User).GetProperty("Name").GetValue(user,null).ToString();

0

你可以使用反射和索引器自己构建它。

但是你需要这样的解决方案吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接