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

165 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
Antonín Procházka 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};
        }
    }
}