My current scenario is that, I am writing a library in C# that performs some task. But the tasks will need to run first, then halfway, it needs some input from the caller before it can continue with the rest of the tasks in the same function. How can I achieve this sort of scenario as I am not sure what is the keyword that I should search for.
For example in the library there is a function:
public bool DoSomething()
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = SomeWorkToBeDoneByCaller(); // ***How to achieve this?
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
CodePudding user response:
You could pass in a Func<string>
callback parameter:
public bool DoSomething(Func<string> someWorkToBeDoneByCaller)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = someWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
Then the call would look like:
libobj.DoSomething(() => "foo");
or
libobj.DoSomething(MyFunc);
string MyFunc() { return "foo"; }
More about Func<T>
here: https://docs.microsoft.com/en-us/dotnet/api/system.func-1
CodePudding user response:
There are a few ways to achieve this. One is to feed the caller into the method
public bool DoSomething(MyClass callerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = callerClass.SomeWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
I've used the above pattern for a few things, depending on your use case it can do the trick (depending on the nature of the work I'd reccomend making it async too but that's a whole other thing)
Another way is to pass in delegate methods (change the <> arguments to change the method's signature, and use Action if the method returns void)
public bool DoSomething(Func<ReturnClass,string,string> methodFromCallerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = methodFromCallerClass("foo","Bar");
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
and you can use linq to make passing in the delegate easier if the signatures don't match 100% something like (x,y) => Foo(x,y,"bar") changes the method from having three parameters to two