Skip to content

Commit 1398210

Browse files
Fixes #4505 - TaskResultConverter properly returns default value in case task is not set or has not completed.
Updated description to include unset Task scenario (i.e. null being passed in) Updated to include proper default value return for Value types Included value passthru for non-Task values
1 parent b8ec35e commit 1398210

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

Microsoft.Toolkit.Uwp.UI/Converters/TaskResultConverter.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,34 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
1515
/// completed yet will block the current thread and might cause a deadlock (eg. if the task was
1616
/// scheduled on the same synchronization context where the result is being retrieved from).
1717
/// The methods in this converter will safely return <see langword="default"/> if the input
18-
/// task is still running, or if it has faulted or has been canceled.
18+
/// task is not set yet, still running, has faulted, or has been canceled.
1919
/// </summary>
20+
/// <seealso href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/default-values">Default values of C# types</seealso>
2021
public sealed class TaskResultConverter : IValueConverter
2122
{
2223
/// <inheritdoc/>
2324
public object Convert(object value, Type targetType, object parameter, string language)
2425
{
26+
//// Check if we need to return a specific type, which only matters for value types where the default won't be null.
27+
var hasValueTypeTarget = targetType is not null && targetType.IsValueType;
28+
//// If we have a value type, then calculate it's default value to return, as we probably need it unless the task is completed.
29+
var defaultValue = hasValueTypeTarget ? Activator.CreateInstance(targetType) : null;
30+
2531
if (value is Task task)
2632
{
27-
return task.GetResultOrDefault();
33+
// If we have a task, check if we have a result now, otherwise the non-generic version of this
34+
// function always returns null, so we want to use whatever we actually want the default value to be
35+
// for our target type (in case it's a value type).
36+
return task.GetResultOrDefault() ?? defaultValue;
37+
}
38+
else if (value is null)
39+
{
40+
// If we have a value type, return that value, otherwise this will be null.
41+
return defaultValue;
2842
}
2943

30-
return DependencyProperty.UnsetValue;
44+
// Otherwise, we'll just pass through whatever value/result was given to us.
45+
return value;
3146
}
3247

3348
/// <inheritdoc/>

0 commit comments

Comments
 (0)