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
}
}
此代码由上网址引用。
A(scrollToEndHandler)和B(scrollToEndHandler)在一个函数中。
更改'AutoScrollToEndProperty'时,将始终调用'OnAutoScrollToEndChanged'。
我想知道这些是否是相同的参考。感谢。
答案 0 :(得分:4)
如果您的问题基本上是“取消订阅实际上在这里有效吗?”答案是C#编译器特定于实现,理论上。
实际上,lambda表达式的主体不捕获任何局部变量,但捕获this
(通过引用listBox
)...所以我期望编译器生成一个包含lambda表达式中代码主体的实例方法。
如果在同一个目标上多次调用该方法(即this
指的是同一个对象),我希望scrollToEndHandler
每次都是一个独特但相等的委托 - 换句话说,它会在每次调用中创建一个新的委托对象(如果lambda表达式没有捕获任何内容,它可能不会,并且可以实现为静态方法并且委托缓存)。但事件订阅/取消订阅仍然有效,因为委托是相同的(指同一方法的相同目标)。
如果lambda表达式引用方法中的任何局部变量,那么事件处理将不会工作,因为编译器将通过包含相关变量和a的单独嵌套类来捕获这些局部变量委托代码的方法,OnAutoScrollToEndChanged
的每个方法调用都会创建该嵌套类的新实例,导致不相等的委托。
正如我所说,这是所有特定于实现的......最好将该代码移动到一个单独的实例方法中,以使其更清楚,它将起作用。