Access result of Task<T> without knowing T - postsharp

145 Views Asked by At

I am trying to use postsharp modify the return values of async methods. Is it possible to get the result of a Task at runtime without knowing T?

i.e.

public void OnSuccess(MethodExecutionArgs args)
{

var returnValue = args.ReturnValue;

// returnType is Task<T>
var returnType = returnValue.GetType();    

// Is it possible to access the result of the task?

// If T was known then I could cast:
// ((Task<T>) returnValue).ContinueWith(t => t.Result ...)
}
1

There are 1 best solutions below

0
On BEST ANSWER

Without reflection, you'd need to use and interface. Also with PostSharp 5.0, you get the result itself there in the OnSuccess method instead of the Task<>.

This example works with PostSharp 5.0:

using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace OnMethodBoundaryAsyncTest
{
    interface IDirtiness
    {
        bool Dirty { get; set; }
    }

    class MyClassWithSomeDirtyObjects : IDirtiness
    {
        public bool Dirty { get; set; }
    }

    [PSerializable]
    class ReportDirtinessAttribute : OnMethodBoundaryAspect
    {
        public override void OnSuccess( MethodExecutionArgs args )
        {
            IDirtiness maybeDirtyObject = args.ReturnValue as IDirtiness;

            if ( maybeDirtyObject != null )
            {
                string dirty = maybeDirtyObject.Dirty ? "is" : "is not";
                Console.WriteLine($"{maybeDirtyObject} {dirty} dirty.");
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            CreateObject( false ).GetAwaiter().GetResult();
            CreateObject( true ).GetAwaiter().GetResult();
        }

        [ReportDirtiness(ApplyToStateMachine = true)]
        static async Task<MyClassWithSomeDirtyObjects> CreateObject( bool dirty )
        {
            return new MyClassWithSomeDirtyObjects {Dirty = dirty};
        }
    }
}