【问题标题】:How to cast object to method return type如何将对象转换为方法返回类型
【发布时间】:2015-08-26 17:51:18
【问题描述】:

我想将args.ReturnValue 设置为从TResponse<T> 方法创建的对象的实例Create

[Serializable]
public sealed class LogError : OnMethodBoundaryAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        // Logging part..

        MethodInfo methodInfo = (MethodInfo)args.Method;

        // I want to replace line below comment to get TResponse<T> object instead of dynamic if possible
        dynamic returnValue = Activator.CreateInstance(methodInfo.ReturnType);
        args.ReturnValue = returnValue.Create(CodeMessage.InternalError, MessageType.Error, args.Exception);

        args.FlowBehavior = FlowBehavior.Return;
    }
}

方法ReturnType 将始终为TResponse&lt;T&gt;,但我不知道如何根据方法返回类型创建TResponse&lt;T&gt; 的实例。 TResponse&lt;T&gt; 使用此签名实现方法:

.Create(CodeMessage.InternalError, MessageType.Error, args.Exception);

Create 方法是静态方法,返回带有参数的TResponse&lt;T&gt; 对象。

由于我不知道如何做我想做的事,我使用Activator 创建方法返回类型的实例并将其存储到dynamic 类型,但是当我调用Create 方法时它会抛出RuntimeBinderException

【问题讨论】:

  • 你试过methodInfo.ReturnType.GetConstructor(...).Invoke(...)吗?
  • @BastiM 谢谢,你的评论帮助了我;)

标签: c# dynamic reflection casting postsharp


【解决方案1】:

由于Create(...) 是静态的,因此您无需使用Activator 类创建实例。只需从 ReturnType 中获取 MethodInfo 并使用 null 作为第一个参数调用它:

public override void OnException(MethodExecutionArgs args)
{
    // Logging part..

    MethodInfo methodInfo = (MethodInfo)args.Method;

    MethodInfo create = methodInfo.ReturnType.GetMethod(
                    "Create",
                    new[] { typeof(CodeMessage), typeof(MessageType), typeof(Exception) });
    args.ReturnValue = create.Invoke(null, new object[] { CodeMessage.InternalError, MessageType.Error, args.Exception });

    args.FlowBehavior = FlowBehavior.Return;
}

MethodInfo.Invoke 返回一个object。由于MethodExecutionArgs.ReturnValue 也只是一个object,因此您不需要转换为实际的TResponse 类型。

不管怎样,如果你需要在返回值上设置一些额外的属性,我会为TResponse&lt;T&gt;引入一个非泛型接口。然后,您可以将结果值转换为该接口并设置属性。

【讨论】:

  • 我自己根据 Basti M 的评论想出来的。感谢您的宝贵时间,这正是我所做的 :)
  • 因为它是一个静态方法,我认为你不能有一个通用的接口。没有?
  • @V.Couvigou: Create(...) 显然不能成为接口的一部分,但想象一下像string AdditionalErrorInfo { get; set; }这样的属性
猜你喜欢
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多