c#如何使用委托将不同的函数传递给另一个函数

c#如何使用委托将不同的函数传递给另一个函数,c#,delegates,C#,Delegates,我的问题是这样的。我有几个功能: public List<FtpDirectoryEntry> ListDirectory(); public bool DirectoryExists(string dir); public void UploadFile(string file); public void UploadFiles(params string[] files); 公共列表列表目录(); 公共布尔目录存在(字符串目录); 公共无效上传文件(字符串文件); 公共无效上载

我的问题是这样的。我有几个功能:

public List<FtpDirectoryEntry> ListDirectory();
public bool DirectoryExists(string dir);
public void UploadFile(string file);
public void UploadFiles(params string[] files);
公共列表列表目录();
公共布尔目录存在(字符串目录);
公共无效上传文件(字符串文件);
公共无效上载文件(参数字符串[]文件);
我想写一个函数来运行这些函数5次。如果我们不能在5次中得到结果,它将抛出异常

public void CheckFunctionWithTrials( function X)
{
    for (int i = 0; i < 5; i++)
    {
        try
        {
            X;
            break;
        }
        catch (Exception e)
        {
            if (i == 5 - 1)
            {
                throw e;
            }
            else
            {
                DLog.Warn("Failed to upload file. Retry #" + (i + 1) + ": " + path);
                Thread.Sleep(1000);
            }
        }
    }
}
public void checkfunction with trials(功能X)
{
对于(int i=0;i<5;i++)
{
尝试
{
X;
打破
}
捕获(例外e)
{
如果(i==5-1)
{
投掷e;
}
其他的
{
DLog.Warn(“未能上载文件。重试#”+(i+1)+:“+path”);
睡眠(1000);
}
}
}
}

问题是这些函数有不同的签名,所以我不能使用委托将它们作为参数传递。有什么方法或模式可以帮助我解决这个问题吗?

请注意,这不使用委托,而是使用
Func
操作
类型

我会把你的签名改成这样:

public void CheckFunctionWithTrials(Action X)
这允许您传入一个不带参数且不返回任何内容的函数。然后,您可以使用类似这样的匿名函数调用它来“删除”参数

CheckFunctionWithTrials(() => UploadFile(file));
这将使您的完整功能看起来像这样:

    public void CheckFunctionWithTrials(Action X)
    {
        foreach (var i in Enumerable.Range(1, 5))
        {
            try
            {
                X?.Invoke();
                break;
            }
            catch (Exception e)
            {
                if (i == 5)
                {
                    throw;
                }
                else
                {
                    //DLog.Warn("Failed to upload file. Retry #" + (i) + ": " + path);
                    Thread.Sleep(1000);
                }
            }
        }
    }
bool exists = CheckFunctionWithTrials(() => DirectoryExists(dir));
在某些函数上也有返回类型,要使其正常工作,需要泛型

    public T CheckFunctionWithTrials<T>(Func<T> X)
    {
        foreach (var i in Enumerable.Range(1, 5))
        {
            try
            {
                return X();
            }
            catch (Exception e)
            {
                if (i == 5)
                {
                    throw;
                }
                else
                {
                    //DLog.Warn("Failed to upload file. Retry #" + (i) + ": " + path);
                    Thread.Sleep(1000);
                }
            }
        }
    }
UPDATE:
实际上,我的一个本地repo中有一个类似的函数,可以重试一次
任务。相同的基本概念,就像
async
方法一样

    public async static Task<T> RetryOnceAsync<T>(this Func<Task<T>> tsk, TimeSpan wait)
    {
        try
        {
            return await tsk?.Invoke();
        }
        catch (Exception ex)
        {
            Logger.Error(ex.Message);
            await Task.Delay(wait);
            return await tsk?.Invoke();
        }
    }
public异步静态任务RetryOnceAsync(此函数tsk,TimeSpan等待)
{
尝试
{
return wait tsk?.Invoke();
}
捕获(例外情况除外)
{
记录器错误(例如消息);
等待任务。延迟(等待);
return wait tsk?.Invoke();
}
}

注意,这不使用委托,而是使用
Func
Action
类型

我会把你的签名改成这样:

public void CheckFunctionWithTrials(Action X)
这允许您传入一个不带参数且不返回任何内容的函数。然后,您可以使用类似这样的匿名函数调用它来“删除”参数

CheckFunctionWithTrials(() => UploadFile(file));
这将使您的完整功能看起来像这样:

    public void CheckFunctionWithTrials(Action X)
    {
        foreach (var i in Enumerable.Range(1, 5))
        {
            try
            {
                X?.Invoke();
                break;
            }
            catch (Exception e)
            {
                if (i == 5)
                {
                    throw;
                }
                else
                {
                    //DLog.Warn("Failed to upload file. Retry #" + (i) + ": " + path);
                    Thread.Sleep(1000);
                }
            }
        }
    }
bool exists = CheckFunctionWithTrials(() => DirectoryExists(dir));
在某些函数上也有返回类型,要使其正常工作,需要泛型

    public T CheckFunctionWithTrials<T>(Func<T> X)
    {
        foreach (var i in Enumerable.Range(1, 5))
        {
            try
            {
                return X();
            }
            catch (Exception e)
            {
                if (i == 5)
                {
                    throw;
                }
                else
                {
                    //DLog.Warn("Failed to upload file. Retry #" + (i) + ": " + path);
                    Thread.Sleep(1000);
                }
            }
        }
    }
UPDATE:
实际上,我的一个本地repo中有一个类似的函数,可以重试一次
任务。相同的基本概念,就像
async
方法一样

    public async static Task<T> RetryOnceAsync<T>(this Func<Task<T>> tsk, TimeSpan wait)
    {
        try
        {
            return await tsk?.Invoke();
        }
        catch (Exception ex)
        {
            Logger.Error(ex.Message);
            await Task.Delay(wait);
            return await tsk?.Invoke();
        }
    }
public异步静态任务RetryOnceAsync(此函数tsk,TimeSpan等待)
{
尝试
{
return wait tsk?.Invoke();
}
捕获(例外情况除外)
{
记录器错误(例如消息);
等待任务。延迟(等待);
return wait tsk?.Invoke();
}
}

如果您甚至不知道这些函数的参数,您希望如何调用其中一个函数?@DavidG我知道它不起作用。但是它可以帮助我解释我想做什么,尽管它没有任何意义。即使你把它们传递进来,你会在
CheckFunctionWithTrials
方法中给它们什么参数?如果你甚至不知道它们取什么参数,你希望如何调用其中一个函数?@DavidG我知道它不起作用。但是它可以帮助我解释我想做什么,尽管它没有任何意义。即使您将它们传入,您会在
CheckFunctionWithTrials
方法中为它们提供哪些参数?