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
This commit is contained in:
michael-hawker 2022-10-20 15:19:09 -07:00 коммит произвёл Michael Hawker MSFT (XAML Llama)
Родитель b8ec35e080
Коммит 1398210158
1 изменённых файлов: 18 добавлений и 3 удалений

Просмотреть файл

@ -15,19 +15,34 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
/// completed yet will block the current thread and might cause a deadlock (eg. if the task was
/// scheduled on the same synchronization context where the result is being retrieved from).
/// The methods in this converter will safely return <see langword="default"/> if the input
/// task is still running, or if it has faulted or has been canceled.
/// task is not set yet, still running, has faulted, or has been canceled.
/// </summary>
/// <seealso href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/default-values">Default values of C# types</seealso>
public sealed class TaskResultConverter : IValueConverter
{
/// <inheritdoc/>
public object Convert(object value, Type targetType, object parameter, string language)
{
//// Check if we need to return a specific type, which only matters for value types where the default won't be null.
var hasValueTypeTarget = targetType is not null && targetType.IsValueType;
//// If we have a value type, then calculate it's default value to return, as we probably need it unless the task is completed.
var defaultValue = hasValueTypeTarget ? Activator.CreateInstance(targetType) : null;
if (value is Task task)
{
return task.GetResultOrDefault();
// If we have a task, check if we have a result now, otherwise the non-generic version of this
// function always returns null, so we want to use whatever we actually want the default value to be
// for our target type (in case it's a value type).
return task.GetResultOrDefault() ?? defaultValue;
}
else if (value is null)
{
// If we have a value type, return that value, otherwise this will be null.
return defaultValue;
}
return DependencyProperty.UnsetValue;
// Otherwise, we'll just pass through whatever value/result was given to us.
return value;
}
/// <inheritdoc/>