在函数中使用匿名事件

时间:2016-01-25 07:04:59

标签: c# events lambda anonymous-function

public static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
    /* ... */

    var scrollToEndHandler = new NotifyCollectionChangedEventHandler((sender, args) => // 수정
    {
        if (listBox.Items.Count > 0)
        {
            object lastItem = listBox.Items[listBox.Items.Count - 1];

            listBoxItems.MoveCurrentTo(lastItem);
            listBox.ScrollIntoView(lastItem);
        }
    });

    if (isAutoScroll)
    {
        source.CollectionChanged += scrollToEndHandler; // A
    }
    else
    {
        source.CollectionChanged -= scrollToEndHandler; //B
    }
}
  

Needed result after loading the window

此代码由上网址引用。

A(scrollToEndHandler)和B(scrollToEndHandler)在一个函数中。

更改'AutoScrollToEndProperty'时,将始终调用'OnAutoScrollToEndChanged'。

我想知道这些是否是相同的参考。感谢。

1 个答案:

答案 0 :(得分:4)

如果您的问题基本上是“取消订阅实际上在这里有效吗?”答案是C#编译器特定于实现,理论上。

实际上,lambda表达式的主体不捕获任何局部变量,但捕获this(通过引用listBox)...所以我期望编译器生成一个包含lambda表达式中代码主体的实例方法。

如果在同一个目标上多次调用该方法(即this指的是同一个对象),我希望scrollToEndHandler每次都是一个独特但相等的委托 - 换句话说,它会在每次调用中创建一个新的委托对象(如果lambda表达式没有捕获任何内容,它可能不会,并且可以实现为静态方法并且委托缓存)。但事件订阅/取消订阅仍然有效,因为委托是相同的(指同一方法的相同目标)。

如果lambda表达式引用方法中的任何局部变量,那么事件处理将不会工作,因为编译器将通过包含相关变量和a的单独嵌套类来捕获这些局部变量委托代码的方法,OnAutoScrollToEndChanged的每个方法调用都会创建该嵌套类的新实例,导致不相等的委托。

正如我所说,这是所有特定于实现的......最好将该代码移动到一个单独的实例方法中,以使其更清楚,它将起作用。