我正在尝试创建一个表单,在处理特定任务时将某些内容设置为动画(作为委托传递给构造函数)。它运行正常,但我遇到的问题是,如果我想要执行的特定方法的返回类型为void,我无法实例化我的泛型类的副本。
我知道这是设计和所有,但我想知道是否有针对这种情况的已知解决方法。
如果它有助于我的所有窗体看起来像这样(为了简洁而修剪):
public partial class operatingWindow<T> : Form
{
public delegate T Operation();
private Operation m_Operation;
private T m_ReturnValue;
public T ValueReturned { get { return m_ReturnValue; } }
public operatingWindow(Operation operation) { /*...*/ }
}
我称之为:
operatingWindow<int> processing = new operatingWindow<int>(new operatingWindow<int>.Operation(this.doStuff));
processing.ShowDialog();
// ...
private int doStuff()
{
Thread.Sleep(3000);
return 0;
}
答案 0 :(得分:6)
不,你需要创建一个重载才能做到这一点。
e.g。
public operatingWindow(Action action)
{
m_Operation=() => { action(); return null; }
}
此外,您无需定义自己的委托,也可以使用Func<T>
和操作。
答案 1 :(得分:4)
我会稍微重新考虑你的设计。
如果您在基类中实现了处理,则可以使用两个几乎可互换的替代方法对其进行子类化。
第一个可能和你的一样,它需要一个返回值的Operation。 (不过我会使用Func<T>
而不是拥有自己的委托类型来重写它。
第二个可能只是采取一个简单的Action而不提供返回值。两者都可以使用相同的动画/显示/等。例程,但提供不同的工作方式。您也可以使用基类将其传递给其他方法,这将提供很大的灵活性。
使用这种方法,你可以这样称呼:
private void DoSleep()
{
Thread.CurrentThread.Sleep(5000);
}
private int ReturnSleep()
{
Thread.CurrentThread.Sleep(5000);
return 5000;
}
...
{
var actionWindow = new OperatingWindowAction(this.DoSleep);
actionWindow.Execute();
var funcWindow = new OperatingWindowFunc<int>(this.ReturnSleep);
funcWindow.Execute();
int result = funcWindow.Result;
}
这看起来像是:
public abstract partial class OperatingWindowBase : Form
{
public void Execute()
{
// call this.OnExecute(); asyncronously so you can animate
}
protected abstract void OnExecute();
}
public class OperatingWindowFunc<T> : OperatingWindowBase
{
Func<T> operation;
public T Result { get; private set; }
public OperatingWindowFunc<T>(Func<T> operation)
{
this.operation = operation;
}
protected override OnExecute()
{
this.Result = operation();
}
}
public class OperatingWindowAction
{
Action operation;
public OperatingWindow(Action operation)
{
this.operation = operation;
}
protected override OnExecute()
{
operation();
}
}