紧凑框架Func<;T>;问题

本文关键字:gt 问题 lt Func 框架 | 更新日期: 2023-09-27 17:59:15

我正试图在后台工作进程上做一些工作,当工作完成时,我想显示一个模式对话框。我已经让代码很好地用于一个简单的Action委托,但希望能够传入一个Func委托并获得一个返回类型。到目前为止,我有一个方法的表格

    public void ShowDialogWhile(Action work)
    {
        _work = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
    }

我接下来想做的是类似的工作

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
        return (TResult)Result;
    }

到目前为止,我还没有任何运气,因为我在声明我的_workWithReturn 类型时一直摔倒

        Func<TResult> _workWithReturn;

有人有什么想法吗?

这是完整的代码。

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    BackgroundWorker _worker = new BackgroundWorker();
    Action _work;
    Func<TResult> _workWithReturn;
    public object Result { get; private set; }

    public AsyncWaitDialog()
    {
        InitializeComponent();
        _worker.DoWork += HandleDoWorkEvent;
        _worker.RunWorkerCompleted += HandleWorkerCompleted;
    }

    public void ShowDialogWhile(Action work)
    {
        _work = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
    }
    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
        return (TResult)Result;
    }

    private void HandleDoWorkEvent(object sender, EventArgs e)
    {
        try
        {
            if (_work != null)
            {
                _work();
            }
            if (_workWithReturn != null)
            {
                Result = _workWithReturn();
            }
        }
        catch (Exception)
        {
            this.Close();
            throw;
        }
    }
    private void HandleWorkerCompleted(object sender, EventArgs e)
    {
        this.Close();
    }
}

紧凑框架Func<;T>;问题

编译时收到的错误与Compact框架无关,而是泛型的错误使用。正如其他人所说,除非在类本身上声明类型TResult,否则它在类中超出了作用域。

如果我看看你试图实现的目标,我会说你可以通过将所有类型特定于方法的局部来获得你想要的。更改如下:

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    ...
    //Func<TResult> _workWithReturn; REMOVE THIS LINE
    ...
    //Change your function to be this:
    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        var result = default(TResult);
        _work = () =>
        {
            result = work();
        };
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
        return result;
    }
}

您的"工作"现在由一个匿名委托执行,该委托调用您的函数,并且函数的返回位于ShowDialogWhile函数的范围内。漂亮又简单的把戏。

为了进行重构,您可以使用现有的方法来处理worker和对话框逻辑:

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        var result = default(TResult);
        ShowDialogWhile(() =>
        {
            result = work();
        });
        return result;
    }

您有一个带有TResult的泛型方法,但也有一个使用该类型的字段。如果在运行时需要该类型的字段,请将泛型定义从方法移动到类。

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    ...
    Func<TResult> _workWithReturn; //TRESULT IS NOT IN SCOPE
    ...
    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        //TResult **IS** in scope here
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
        return (TResult)Result;
    }

// possible solution, move the generic definition of TResult to the class definition
public partial class AsyncWaitDialog<TResult> : Form, IAsyncDialog { ... }

您的问题是TResult是在ShowDialogWhile方法上定义的泛型,但您已经声明了超出该范围的_workWithReturn。一种修复方法是将TResult作为类声明的一部分。