I am using Visual Studio 2015 and I have below two statements.
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 warns me that
Task.Factory.StartNew<List<int>>((stateObj)
can be simplified to
Task.Factory.StartNew((stateObj)
As I can see I can even use it without any type and VS infers generic type from lambda expression return value type, as below:
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);
But this is not applicable to the first statement. In this case, VS force me to include generic types.
Could you please help me, why these two behaves differently?
The two code samples do different things. Easiest way to see this is to put a break-point in the function of both parts and to press F5. It will hit the break-point of the second part even though it is below the first.
Now for the explanation:
The first one is just creating a generic object and when calling the constructor you must explicitly say what type you are creating.
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;
});
So when you write new ...
you must specify what type.
However, in the second section you are executing a function which returns an object and you are assigning it to a variable.
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);
At this point the task has already been executed and is running in the background. Because you are not directly instantiating the object visual studio tells you that the return type can be inferred and therefore "name can be simplified".
If you look visual studio also says you can await
it while it doesn't say that to the first section:
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);
Simple design perspective:
Generic Constructor
, then type needs to be mandatory supplied and that's what flows to the parameters, which they need to strictly adhereGeneric Method
, then type may be defined using the method Output, and that needs to be adhered by the Type returned.Thus the role reversal in the two cases defined above
Case 1: Using Generic Constructor
Initialization is done using Task
class constructor, since we are using the generic version, therefore Task<T>
constructor, check out the various options on the following link. Important point remains that Task<TResult>
type is taking parameter as Func
delegate with TResult
as Output, where type of Output is mapped using the Task<TResult>
, that's why its mandatory to define the type for Task class, during initialization, its not the other way round. It is not possible to use a Func
delegate as parameter, whose return type is not TResult
(by design), thus enforcing the strict type check. Constructor used in this case is following.
Task<TResult>(Func<TResult>)
Case 2: Using Generic Method
In this case Task.Factory.StartNew<TResult>(Func<TResult>)
method is used to create a Task
object, where the return type of the Task
is managed by the Func
delegate and its return type, thus the type checking is still enforced but its opposite to the first case, therefore Task returned should have the same type as the Func
delegate, check the following link
In case of Visual studio its able to pick up the nuance details from the compiler, which it runs on every modification and can suggest, whether change is optional / mandatory and accordingly user is prompted for an action and thus graying out the optional code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With