在不知道 T 的情况下访问 Task<T> 的结果 - postsharp

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

我正在尝试使用 postsharp 修改异步方法的 return 值。是否可以在不知道 T 的情况下在运行时获取 Task 的结果?

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 ...)
}

没有反射,你需要使用和接口。同样对于 PostSharp 5.0,您可以在 OnSuccess 方法中获得结果本身,而不是 Task<>.

此示例适用于 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};
        }
    }
}