我想重构一些异步创建 ViewModel 的函数。他们看起来如下:
public async Task NavigateToCreateFormVM()
{
try
{
IsLoading = true;
CurrentVM = await Task.Run(() => new CreateFormVM());
<...>
IsLoading = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "App", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
所以为了重构所有逻辑,我尝试编写一个委托来保持代码易于维护。
public async Task NavigationDelegate(Func<Task<BaseVM>> delegate)
{
try
{
IsLoading = true;
CurrentVM = await delegate();
<...>
IsLoading = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "App", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
例如将我的功能更改为:
public async Task NavigateToCreateFormVM()
{
await NavigationDelegate(() => Task.Run(() => new CreateFormVM()));
}
public async Task NavigateToConsultFormVM()
{
await NavigationDelegate(() => ConsultFormVM.CreateAsync()); // type of ConsultFormVM
}
但是我收到两条错误消息,表明它们无法将 CreateFormVM/ConsultFormVM 转换为 BaseVM(它们都来自 BaseVM)。如果我将
NavigationDelegate(Func<Task<BaseVM>> delegate)
更改为 NavigationDelegate(Func<Task<CreateFormVM>> delegate)
它可以正常工作。
错误消息为 CS0029 和 CS1662。
无法将类型“System.Threading.Tasks.Task
”隐式转换为“System.Threading.Tasks.Task ” 无法将匿名方法块转换为委托类型,因为块中的某些返回类型不能隐式转换为委托返回类型
我不知道我是否遗漏了某些东西,或者我是否做错了什么(或者根本不应该这样做?),所以如果有人知道如何解决我的问题,我将不胜感激。
Func<T>
的类型参数不是逆变的,Task<T>
的类型参数不是协变的。所以你不能做这些:
public class Base
{
}
public class Derived : Base
{
}
public static void Main()
{
Func<Task<Base>> d = GetBase;
Func<Task<Derived>> e = d; // Will fail
Task<Base> dd = GetDerived(); // Will fail
}
public static Task<Base> GetBase()
{
return Task.FromResult(new Base());
}
public static Task<Derived> GetDerived()
{
return Task.FromResult(new Derived());
}