Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have a chunk of code that does a "file put" operation inside a moderately complicated piece of retry and try/catch logic. This is working fine, it looks roughly like this:
while (...) {
try {
FilePut(source, destination)
catch () {
//Check exception type, possibly re-throw, possibly return, possibly increment
//counters being checked by while loop
The details of this logic aren't the issue. But I'm realizing I have several other operations that also need to execute inside this same kind of logic and I want to avoid copy and pasting this logic around my application. I'd like to move it to a function and reuse that function. That function would have to take some sort of reference to the operation to be called, and the try logic would execute that operation (file put, file get, whatever).
This seems like a great place for a delegate, but the problem is, each of these operations has a different signature, so I'm not sure how to be able to write my above logic to be able to call "any" operation.
Is there a good way to do this in C#?
You need an Action
delegate to hide all of the different signatures. Something like this:
public void DoAction(Action action)
// Make the boilerplate code whatever you need it to be.
// I've just used a try catch for simplicity.
// Call the action at the appropriate time.
action();
catch
// Handle any exceptions as you wish.
Then, to be able to handle actions with different signatures, you can define a few overloads that take different types of the generic Action<T>
delegates and all of the necessary arguments. These overloads will "curry" the generic action and its arguments to a plain Action
:
public void DoAction<T>(Action<T> action, T arg1)
DoAction(() => action(arg1));
public void DoAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
DoAction(() => action(arg1, arg2));
public void DoAction<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
DoAction(() => action(arg1, arg2, arg3));
// etc...
To use:
public void SomeOtherMethod()
DoAction(MethodThatTakesTwoInts, 42, 23);
DoAction(MethodThatTakesAString, "Don't Panic!");
Also, if you not familiar with them, take a look at the related family of Func
delegates as well for good measure.
–
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.