Reputation: 33
public class Foo : Collection<string>
{
bool _cancel = false;
public void AddWithoutDoingStuff(string item)
{
_cancel = true;
Add(item);
_cancel = false;
}
protected override void InsertItem(int index, string item)
{
base.InsertItem(index, item);
if (!_cancel)
{
//Do some stuff
}
}
}
I wonder if there is a pattern to avoid this ugly _cancel member? I found something here: Temporarily stop form events from either being raised or being handled? But this only works with events.
Edit Sorry I did not express myself well. This is just a example. The explicit base class doesn't matter. What I'm want to ask for is a general solution to avoid the _cancel variable in this case. I don't like the method AddWithoutDoingStuff as it is in this example. It is not save in case of errors, so I have to do something like that:
try
{
_cancel = true;
Add(item);
}
finally
{
_cancel = false;
}
It is also not threat save.
Upvotes: 3
Views: 104
Reputation: 236228
You cannot override the way Add
method works. And it just calls InsertItem
without any additional parameters. That mean the only way to have some additional parameters inside InserItem
is passing them via class fields (your solution).
But if you will not call base Add
method you can control what is done or not done before/after inserting item
public class Foo : Collection<string>
{
public void AddWithoutDoingStuff(string item)
{
if (Items.IsReadOnly())
throw new NotSupportedException();
base.InsertItem(Count, item);
}
protected override void InsertItem(int index, string item)
{
base.InsertItem(index, item);
// Do Some Stuff
}
}
NOTE: Unfortunately checking whether internal Items is readonly done in Add
method of base class. And there is no verification in InsertItem
method. So it would be nice if you'll do same check.
Upvotes: 1
Reputation: 1950
Your Collection
object
has no need for nor should it have a _cancel bool,
especially since we're talking Forms.
If by Forms you mean WinForms, and as we're event
driven here I presume you do, then the proper way to handle this would be to retrieve any cancellation as a parameter from the UI or calling method and resolve it before ever calling the collection. It's better to just not execute a process than execute one and cancel it. Example (undeclared variables are assumed further up the code):
DialogResult dr = MessageBox.Show("Do this?", "Question", MessageButton.OKCancel);
myFoo.InsertItem(myIndex, myItem, (r != DialogResult.Cancel ? true : false);
And of course you'd modify your InsertItem method slightly:
protected void InsertItem(int index, string item, bool _cancel)
{
base.InsertItem(index, item);
if (!_cancel)
{
//Do some stuff
}
}
It doesn't have to be a MessageBox. I just used that to illustrate the proper way to manage your toggle without having that ugly _cancel field in your class.
Also, along the thread of one of the comments now that I'm caffeinating, you should have a collection as a part of the class, notsomuch inherit from Collection.
Upvotes: 0