我正在使用Visual Studio 2015,我有两个以下的陈述。
Task<List<int>> taskWithInLineAction = new Task<List<int>>(() =>
{
List<int> ints = new List<int>();
for (int i = 0; i < 1000; i++)
{
ints.Add(i);
}
return ints;
});
Task<List<int>> taskWithFactoryAndState = Task.Factory.StartNew<List<int>>((stateObj) =>
{
List<int> ints = new List<int>();
for (int i = 0; i < (int)stateObj; i++)
{
ints.Add(i);
}
return ints;
}, 2000);
Vs2015警告我
Task.Factory.StartNew<List<int>>((stateObj)
可以简化为
Task.Factory.StartNew((stateObj)
我可以看到我甚至可以在没有任何类型的情况下使用它,VS从lambda表达式返回值类型推断泛型类型,如下所示:
Task taskWithFactoryAndState = Task.Factory.StartNew((stateObj) =>
{
List<int> ints = new List<int>();
for (int i = 0; i < (int)stateObj; i++)
{
ints.Add(i);
}
return ints;
}, 2000);
但这不适用于第一个声明。在这种情况下,VS强迫我包含泛型类型。
你能帮助我,为什么这两个表现不同?
答案 0 :(得分:4)
这两个代码示例做了不同的事情。最简单的方法是在两个部分的功能上设置一个断点并按下F5。它会达到第二部分的断点,即使它低于第一部分。
现在解释一下:
第一个是创建通用对象,在调用构造函数时,必须明确说明您要创建的类型。
Task<List<int>> taskWithInLineAction = new Task<List<int>>(() =>
{
List<int> ints = new List<int>();
for (int i = 0; i < 1000; i++)
{
ints.Add(i);
}
return ints;
});
所以当你写new ...
时,你必须指定什么类型。
但是,在第二部分中,您执行一个函数,它返回一个对象并将其分配给一个变量。
Task<List<int>> taskWithFactoryAndState = Task.Factory.StartNew<List<int>>((stateObj) =>
{
List<int> ints = new List<int>();
for (int i = 0; i < (int)stateObj; i++)
{
ints.Add(i);
}
return ints;
}, 2000);
此时任务已经执行并在后台运行。因为您没有直接实例化对象,Visual studio会告诉您可以推断返回类型,因此“名称可以简化”。
如果你看起来视觉工作室也说你可以await
它虽然没有说到第一部分:
List<int> taskWithFactoryAndState = await Task.Factory.StartNew<List<int>>((stateObj) =>
{
List<int> ints = new List<int>();
for (int i = 0; i < (int)stateObj; i++)
{
ints.Add(i);
}
return ints;
}, 2000);
答案 1 :(得分:2)
简单的设计视角:
Generic Constructor
初始化对象,则需要强制提供类型,这就是流向参数的内容,这些参数需要严格遵守Generic Method
初始化对象,则可以使用方法Output定义类型,并且需要通过返回的类型来遵守。因此,上述两种情况下的角色转换
案例1:使用通用构造函数
使用Task
类构造函数完成初始化,因为我们使用的是通用版本,因此Task<T>
构造函数,请查看以下link的各种选项。重要的一点是,Task<TResult>
类型将参数作为Func
委托,TResult
作为输出,其中输出的类型使用Task<TResult>
进行映射,这就是为什么必须定义类型为Task类,在初始化期间,它不是相反的方式。无法使用Func
委托作为参数,其返回类型不是TResult
(按设计),因此强制执行严格类型检查。在这种情况下使用的构造函数如下。
Task<TResult>(Func<TResult>)
案例2:使用通用方法
在这种情况下,Task.Factory.StartNew<TResult>(Func<TResult>)
方法用于创建Task
对象,其中Task
的返回类型由Func
委托及其返回类型管理,因此,类型检查仍然是强制执行但与第一种情况相反,因此返回的任务应与Func
委托具有相同的类型,请检查以下link
在Visual Studio的情况下,它能够从编译器中获取细微差别细节,它在每次修改时运行,并且可以建议,更改是可选的/强制的,因此提示用户执行某个操作,从而使可选项变灰代码