簡體   English   中英

如何從非泛型函數返回泛型函數?

[英]How to return a generic function from a non-generic function?

用一個例子可能最容易解釋。

因此,讓我們從下面的TryNTimes函數開始。

public static T TryNTimes<T>(Func<T> f, int n)
{
    var i = 0;
    while (true)
    {
        try
        {
            return f();
        }
        catch
        {
            if (++i == n)
            {
                throw;
            }
        }
    }
}

並像這樣使用

MyType x = TryNTimes(DoSomething, 3);
MyOtherType y = TryNTimes(DoSomethingElse, 3);

但是我經常在N相同的情況下使用它,因此我想簡化創建將n值注入此處的函數的過程。 所以用途是

var tryThreeTimes = CreateRetryWrapper(3);
MyType x = tryThreeTimes(DoSomething);
MyOtherType y = tryThreeTimes(DoSomethingElse);

我能想到的最接近的是

public static Func<Func<T>, T> CreateRetryWrapper<T>(int n)
{
    return f => TryNTimes(f, n);
}

但這並不是我真正想要的,因為它迫使我指定T a-priori,因此它並不是真正按照我想要的方式可重用的。 我希望能夠延遲T ,並返回一個通用函數作為值。 就像是

public static Func<Func<_>, _> CreateRetryWrapper(int n)
{
    return f => TryNTimes(f, n);
}

這在C#中可能嗎?

解決方法:

class RetryWrapper 
{ 
    int n;
    public RetryWrapper(int _n) => n =_n;
    public T Try<T>(Func<T> f) => TryNTimes(f, n);
}

采用:

var tryThreeTimes = new RetryWrapper(3);
MyType x = tryThreeTimes.Try(DoSomething);
MyOtherType y = tryThreeTimes.Try(DoSomethingElse);
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;
                }
            }
        }
    }
}

用法:

RetryWrapper.Create(3).TryNTimes(() => 16);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM