Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 此代码如何处理INotifyPropertyChanged_C#_C# 4.0_Lambda_Extension Methods_Expression Trees - Fatal编程技术网

C# 此代码如何处理INotifyPropertyChanged

C# 此代码如何处理INotifyPropertyChanged,c#,c#-4.0,lambda,extension-methods,expression-trees,C#,C# 4.0,Lambda,Extension Methods,Expression Trees,我在此链接中看到以下代码: 我是表达式树的新手。有人能简单解释一下这段代码是如何工作的吗 谢谢 private string _name; public string Name { get { return _name; } set { PropertyChanged.ChangeAndNotify(ref _name, value, () => Name); } } publicstaticboolchangeandtify(此属性changedeventhandler处

我在此链接中看到以下代码:

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

谢谢

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

publicstaticboolchangeandtify(此属性changedeventhandler处理程序,ref T字段,T值,表达式memberExpression)
{
if(memberExpression==null)
{
抛出新ArgumentNullException(“memberExpression”);
}
var body=memberExpression.body作为memberExpression;
if(body==null)
{
抛出新ArgumentException(“Lambda必须返回属性”);
}
if(EqualityComparer.Default.Equals(字段,值))
{
返回false;
}
var vmExpression=主体。表达式为常量表达式;
if(vmExpression!=null)
{
LambdaExpression lambda=Expression.lambda(vmExpression);
委托vmFunc=lambda.Compile();
对象发送方=vmFunc.DynamicInvoke();
if(处理程序!=null)
{
处理程序(发送方,新属性changedeventargs(body.Member.Name));
}
}
字段=值;
返回true;
}

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

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

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

这是一个扩展方法,它可以通过检查lambda表达式树来确定发送方和属性名称,而不会对性能造成任何重大影响:

public static class PropertyChangedExtensions
{
    public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> property)
    {
        if (handler == null)
            return;

        var boxingExpr = property.Body as UnaryExpression;

        var memberExpr = (MemberExpression)(boxingExpr == null ? 
            property.Body : boxingExpr.Operand);

        var propertyName = memberExpr.Member.Name;
        var sender = ((ConstantExpression)memberExpr.Expression).Value;
        handler.Invoke(sender, new PropertyChangedEventArgs(propertyName));
    }
}

谢谢。你是一个伟大的开发人员。我不明白
这个
这个
这个
在这个例子中指向
属性changedeventhandler
以及lamda expression如何将
这个
名称
组合在一起?is
MemberExpression
是委托(lambda)表达式树的一部分?为什么在第7行中得到表达式的正文,而在第17行中又得到表达式的正文?对不起,这是为我准备的。@Nima不,代理不是lambda的一部分;这只是为了对比。第7行上的位标识表达式实际上是成员访问;第17行的位正在查找对象(
这是我上面讨论的
);他们没有理解整个树,而是选择执行
Compile()
/
DynamicInvoke()
,顺便说一句,这非常慢(相对而言)。同样,我不建议使用这种代码。你说:上面的代码将有一个
ConstantExpression
。如果是这样,为什么在第17行将body转换为
ConstantExpression
?@Nima它没有;
MemberExpression
与C#一样,是对象和成员的组合,即C#
this.Name
;这里,目标对象被指定为一个
表达式
(就像在C#really中一样,即
{some component Expression}.Name
)。它正在测试它是否是常数。@Nima不,不是真的。这是一个有点利基;我在博客上写过一点,等等,但没什么大不了的。老实说,如果你玩一会儿,它会更有意义;p一开始很混乱-别担心,这很正常。你不会发疯的——这东西太疯狂了。
public string Name
{
   get { return _name; }
   set { SomeSimpleNotifyMethod(ref _name, value, this, "Name"; }
}
public static class PropertyChangedExtensions
{
    public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> property)
    {
        if (handler == null)
            return;

        var boxingExpr = property.Body as UnaryExpression;

        var memberExpr = (MemberExpression)(boxingExpr == null ? 
            property.Body : boxingExpr.Operand);

        var propertyName = memberExpr.Member.Name;
        var sender = ((ConstantExpression)memberExpr.Expression).Value;
        handler.Invoke(sender, new PropertyChangedEventArgs(propertyName));
    }
}
public string Name
{
    get { return name; }
    set
    {
        name = value;
        PropertyChanged.Raise(() => Name);
    }
}