As an aside. With your 10+ years of programming experience you are likely aware about pass-by-value vs. pass-by-reference. C# is a pass-by-value language so your
TReturnType returnValue
might be a misnomer. If
TReturnType
is a value type, there is no way for the delegate to return a value. That parameter then essentially should just be treated as an incoming default value or initial value.
public delegate void CallbackType<TReturnType>(bool success, TReturnType defaultValue) where TReturnValue : struct;
In the code example I have in post #4, I deliberately declared the class
Foo
so that I could pass in a reference type, and be able to change values within the instance passed in. (e.g.
Bar
). The
returnValue
parameter would be treated more like a data transfer object.
If the instance needs to be completely replaced but there needs to be a way to pass in an initial value, then marking it as
ref
would be more appropriate. e.g.
public delegate void CallbackType<TReturnType>(bool success, ref TReturnType value);
If the delegate's intent is truly to return a value and there is no need to pass in an initial or default value, then the parameter should be marked as
out
. e.g.
public delegate void CallbackType<TReturnType>(bool success, out TReturnType returnValue);
But then this also leads to another design issue. If a function only has one
out
parameter, and the function currently returns
void
, a better design would be to change the signature to return a type of that
TReturnType
. .e.g.
public delegate TReturnType CallbackType<TReturnType>(bool success);