DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="5.17.2" />

 TaskResultBinder

using System; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; namespace DotNext.Dynamic { [RequiresDynamicCode("DLR is required to resolve underlying task type at runtime")] [RequiresUnreferencedCode("Dynamic code generation may be incompatible with IL trimming")] internal sealed class TaskResultBinder : CallSiteBinder { private static Expression BindProperty(PropertyInfo resultProperty, Expression target, out Expression restrictions) { restrictions = Expression.TypeIs(target, resultProperty.DeclaringType); target = Expression.Call(typeof(Unsafe), "As", new Type[1] { resultProperty.DeclaringType }, target); target = Expression.Property(target, resultProperty); if (!target.Type.IsValueType) return target; return Expression.Convert(target, typeof(object)); } private static Expression Bind(object targetValue, Expression target, LabelTarget returnLabel) { target = BindProperty(targetValue.GetType().GetProperty("Result", BindingFlags.Instance | BindingFlags.Public), target, out Expression restrictions); target = Expression.Return(returnLabel, target); target = Expression.Condition(restrictions, target, Expression.Goto(CallSiteBinder.UpdateLabel)); return target; } public override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) { return Bind(args[0], parameters[0], returnLabel); } } }