使用 C# 事件递归
Recursion with C# Event
我正在调试 Microsoft prism 库中的一些代码。即一个名为 ModuleCatalog:
的 class
public class AppModuleCatalog : IAppModuleCatalog
{
private readonly ModuleCatalogItemCollection _items;
private bool _isLoaded;
public Collection<IAppModuleCatalogItem> Items
{
get { return (Collection<IAppModuleCatalogItem>)this._items; }
}
public AppModuleCatalog()
{
this._items = new ModuleCatalogItemCollection();
this._items.CollectionChanged += new NotifyCollectionChangedEventHandler(this.ItemsCollectionChanged);
}
public virtual void AddModule(AppModuleInfo moduleInfo)
{
Argument.IsNotNull("moduleInfo", moduleInfo);
this.Items.Add(moduleInfo);
}
public AppModuleCatalog AddModule(string moduleName, string moduleType, string refValue, InitializationMode initializationMode, params string[] dependsOn)
{
Argument.IsNotNull("ModuleName", moduleName);
Argument.IsNotNull("moduleType", moduleType);
AppModuleInfo moduleInfo = new AppModuleInfo(moduleName, moduleType);
moduleInfo.DependsOn.AddRange(dependsOn);
moduleInfo.InitializationMode = initializationMode;
moduleInfo.Ref = refValue;
this.Items.Add(moduleInfo);
return this;
}
private void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (!this.Validated)
return;
this.EnsureCatalogValidated();
}
.
.
.
private class ModuleCatalogItemCollection : Collection<IAppModuleCatalogItem>, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void InsertItem(int index, IAppModuleCatalogItem item)
{
InsertItem(index,item);
this.OnNotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
protected void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs eventArgs)
{
if (this.CollectionChanged == null) return;
this.CollectionChanged(this, eventArgs);
}
}
}
初始化此 class 时,将调用 AddModule 方法将 ModuleInfo 添加到 Items 属性。我注意到的是,然后调用私有 class 并在 InsertItem 方法中重复进行递归调用,这当然会导致 OverFlow 异常。请注意 getter 来自 Items 属性 returns _items
你能解释一下为什么会发生递归吗?
根据 original source code,ModuleCatalogItemCollection.InsertItem(int, IModuleCatalogItem)
方法实现如下所示:
protected override void InsertItem(int index, IModuleCatalogItem item)
{
base.InsertItem(index, item);
this.OnNotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
注意 base.InsertItem(index, item)
方法调用。这将从 Collection<IModuleCatalogItem>
class 而不是 this.InsertItem()
调用基本方法实现。所以这里没有递归调用。
我正在调试 Microsoft prism 库中的一些代码。即一个名为 ModuleCatalog:
的 classpublic class AppModuleCatalog : IAppModuleCatalog
{
private readonly ModuleCatalogItemCollection _items;
private bool _isLoaded;
public Collection<IAppModuleCatalogItem> Items
{
get { return (Collection<IAppModuleCatalogItem>)this._items; }
}
public AppModuleCatalog()
{
this._items = new ModuleCatalogItemCollection();
this._items.CollectionChanged += new NotifyCollectionChangedEventHandler(this.ItemsCollectionChanged);
}
public virtual void AddModule(AppModuleInfo moduleInfo)
{
Argument.IsNotNull("moduleInfo", moduleInfo);
this.Items.Add(moduleInfo);
}
public AppModuleCatalog AddModule(string moduleName, string moduleType, string refValue, InitializationMode initializationMode, params string[] dependsOn)
{
Argument.IsNotNull("ModuleName", moduleName);
Argument.IsNotNull("moduleType", moduleType);
AppModuleInfo moduleInfo = new AppModuleInfo(moduleName, moduleType);
moduleInfo.DependsOn.AddRange(dependsOn);
moduleInfo.InitializationMode = initializationMode;
moduleInfo.Ref = refValue;
this.Items.Add(moduleInfo);
return this;
}
private void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (!this.Validated)
return;
this.EnsureCatalogValidated();
}
.
.
.
private class ModuleCatalogItemCollection : Collection<IAppModuleCatalogItem>, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void InsertItem(int index, IAppModuleCatalogItem item)
{
InsertItem(index,item);
this.OnNotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
protected void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs eventArgs)
{
if (this.CollectionChanged == null) return;
this.CollectionChanged(this, eventArgs);
}
}
}
初始化此 class 时,将调用 AddModule 方法将 ModuleInfo 添加到 Items 属性。我注意到的是,然后调用私有 class 并在 InsertItem 方法中重复进行递归调用,这当然会导致 OverFlow 异常。请注意 getter 来自 Items 属性 returns _items
你能解释一下为什么会发生递归吗?
根据 original source code,ModuleCatalogItemCollection.InsertItem(int, IModuleCatalogItem)
方法实现如下所示:
protected override void InsertItem(int index, IModuleCatalogItem item)
{
base.InsertItem(index, item);
this.OnNotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
注意 base.InsertItem(index, item)
方法调用。这将从 Collection<IModuleCatalogItem>
class 而不是 this.InsertItem()
调用基本方法实现。所以这里没有递归调用。