【问题标题】:Using Reflection to get a variable's name [duplicate]使用反射获取变量的名称[重复]
【发布时间】:2009-12-04 17:25:31
【问题描述】:

我正在使用 MVVM,在我的一个 VM 中,我有一个 IsEditable 属性(它们都来自一个基类),一系列按钮使用该属性来确定它们的命令是否可以触发。

这个虚拟机还有一个子虚拟机,我需要将这个IsEditable属性回显到它,目前我正在覆盖我的OnPropertyChanged方法来检查正在刷新的属性是否是.Equals("IsEditable")

我有一个唠叨告诉我这不是一个很好的做法,如果这个 IsEditable 将来被重命名,那么这个功能将默默地中断。有没有更好的方法来做到这一点,或者能够使用反射的属性名称,例如:

if (propertyRefreshName.Equals(IsEditable.Name))
{
    // Echo down IsEditable change....
}

【问题讨论】:

  • 在时间紧迫的代码中使用反射通常不是一个好主意,因为它可能非常慢。听起来您将在 UI 线程中运行它。减速可能一开始并不明显,但随着时间的推移,您可能会注意到您的应用开始无缘无故地爬网。我会推荐 Reed 建议的通知机制。

标签: c# reflection


【解决方案1】:

您可以潜在地对人们用来实现 INotifyPropertyChanged 的​​表达式使用相同的技巧。 Eric De Carufel blogged about this.

如果您使用相同的技术,您可以将代码编写为:

if (IsPropertyName(() => this.IsEditable, propertyRefreshName))
{ ... }

这将只需要实现一个函数来检查属性名称,但让您以不使用硬编码字符串的方式进行。

【讨论】:

  • 您的链接中有 _22 会破坏它。应该是blog.decarufel.net/2009/07/…
  • Hrm... 两者都为我工作。 _22 是后天的修订版......
  • 访问时收到“抱歉,您在博客 Eric De C# 中查找的页面不存在”。
  • 很奇怪 - 它在这里为我工作,没有任何问题。
【解决方案2】:

尝试使用扩展方法从对象中获取属性名称

public static class ObjectExtensions
{
    public static string PropertyName<T,TOut>(this T source, Expression<Func<T,TOut>> property)
    {
        var memberExpression = (MemberExpression) property.Body;
        return memberExpression.Member.Name;
    }
}

然后在你的 OnPropertyChanged 中添加

if(propertyRefreshName == this.PropertyName(x => x.IsEditable))
  SubVM.IsEditable = IsEditable;

【讨论】:

    【解决方案3】:

    我同意 statenjason。

    除非我弄错了,否则根据我自己的经验,我了解到表达式树的主体并不总是 MemberExpression(它实际上可以是任何东西),因此需要更多代码。

    请参阅 FluentNHibernate 项目中以下代码中的 GetMemberExpression 方法:

    http://github.com/jagregory/fluent-nhibernate/blob/master/src/FluentNHibernate/Utils/Reflection/ReflectionHelper.cs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-04
      • 2010-10-19
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      • 2011-11-02
      • 2013-09-11
      相关资源
      最近更新 更多