Reputation: 10781
This will probably be easiest to explain with an example.
So, let's start with the following TryNTimes
function.
public static T TryNTimes<T>(Func<T> f, int n)
{
var i = 0;
while (true)
{
try
{
return f();
}
catch
{
if (++i == n)
{
throw;
}
}
}
}
And use it like
MyType x = TryNTimes(DoSomething, 3);
MyOtherType y = TryNTimes(DoSomethingElse, 3);
But I'm using this in many cases with the same N
, so I'd like to make it easy to create a function that injects the n
value into here. So the use would be
var tryThreeTimes = CreateRetryWrapper(3);
MyType x = tryThreeTimes(DoSomething);
MyOtherType y = tryThreeTimes(DoSomethingElse);
The closest I could come up with was
public static Func<Func<T>, T> CreateRetryWrapper<T>(int n)
{
return f => TryNTimes(f, n);
}
But that's not really what I want, because it forces me to specify T
a-priori, so it's not really reusable in the way that I want. I want to be able to delay the T
, returning a generic function as a value. Something like
public static Func<Func<_>, _> CreateRetryWrapper(int n)
{
return f => TryNTimes(f, n);
}
Is this something that's possible in C#?
Upvotes: 1
Views: 76
Reputation: 5234
class RetryWrapper
{
readonly int n;
private RetryWrapper(int n)
{
this.n = n;
}
public static RetryWrapper Create(int n)
{
return new RetryWrapper(n);
}
public T TryNTimes<T>(Func<T> f)
{
var i = 0;
while (true)
{
try
{
return f();
}
catch
{
if (++i == n)
{
throw;
}
}
}
}
}
Usage:
RetryWrapper.Create(3).TryNTimes(() => 16);
Upvotes: 1
Reputation: 6462
workaround:
class RetryWrapper
{
int n;
public RetryWrapper(int _n) => n =_n;
public T Try<T>(Func<T> f) => TryNTimes(f, n);
}
Use:
var tryThreeTimes = new RetryWrapper(3);
MyType x = tryThreeTimes.Try(DoSomething);
MyOtherType y = tryThreeTimes.Try(DoSomethingElse);
Upvotes: 3