紧凑框架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();
}
}
编译时收到的错误与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
作为类声明的一部分。