c# - 此代码如何处理 INotifyPropertyChanged

标签 c# c#-4.0 lambda extension-methods expression-trees

我在此链接中看到以下代码:An elegant way to implement INotifyPropertyChanged

我是表达式树的新手。有人可以简单地解释一下这段代码是如何工作的吗?

谢谢

private string _name;
public string Name
{
   get { return _name; }
   set { PropertyChanged.ChangeAndNotify(ref _name, value, () => Name); }
}

public static bool ChangeAndNotify<T>(this PropertyChangedEventHandler handler,ref T field, T value, Expression<Func<T>> memberExpression)
    {
        if (memberExpression == null)
        {
            throw new ArgumentNullException("memberExpression");
        }
        var body = memberExpression.Body as MemberExpression;
        if (body == null)
        {
            throw new ArgumentException("Lambda must return a property.");
        }
        if (EqualityComparer<T>.Default.Equals(field, value))
        {
            return false;
        }

        var vmExpression = body.Expression as ConstantExpression;
        if (vmExpression != null)
        {
            LambdaExpression lambda = Expression.Lambda(vmExpression);
            Delegate vmFunc = lambda.Compile();
            object sender = vmFunc.DynamicInvoke();

            if (handler != null)
            {
                handler(sender, new PropertyChangedEventArgs(body.Member.Name));
            }
        }

        field = value;
        return true;
    }

最佳答案

表达式树是运行时表达式的面向对象表示。 C# 编译器可以自动将表达式的有限子集编写为 Expression<>实例,通过 lambda - 即

Func<string> anonMethod = () => "abc"; // this is a delegate
Expression<Func<string>> expression = () => "abc"; // this is an expression

上面会有一个ConstantExpression ;您的示例将有 ConstantExpression捕获 this和一个 MemberExpression包装常量 ( this ) 和成员 ( .Name )。然后在运行时,它找到 MemberExpression ,其中有 MemberInfo ,其中有 Name 。它甚至可以有 ConstantExpression捕获类,一个 MemberExpressionthis (作为捕获类上的字段),然后是 MemberExpression.Name .

差异很微妙,但可以在运行时拆分和检查表达式 - 这对于 LINQ 至关重要。然而:虽然编译器可以编写这些,但它们不能自由地检查;他们也有成本。

IMO,也许坚持:

public string Name
{
   get { return _name; }
   set { SomeSimpleNotifyMethod(ref _name, value, this, "Name"; }
}

这更简单、更快(显然,更改方法以获取传递给事件的字符串)。

关于c# - 此代码如何处理 INotifyPropertyChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6829099/

相关文章:

c# - 求csv文件中每一列的最大长度

c# - 如何使用 C# 检查 XML 中具有特定属性值的元素

asp.net-mvc-2 - 我可以从 global.asax 重定向到 Controller 操作吗?

c# - 消除.net lambda 表达式

javascript - 如何使这个 JavaScript 弹出窗口模式化?

c# - 如何在执行或设置时将 visual studio 中的文件路径修改为我的数据库

c# - HttpWebRequest vs Webclient(特殊场景)

c# - 我怎样才能继续上循环

lambda - Kotlin:内联 lambda 和重载解析歧义

c# - 带有 String keySelector 的 OrderBy