简体   繁体   English

传递随机方法作为参数?

[英]Passing a random method as a parameter?

Is there any way in C# to pass a random method as a parameter? C#中有任何方法可以将随机方法作为参数传递吗?

To explain my question: 解释我的问题:

I want to write a simple Logger-Tool that reports the entering and leaving of a method with the passed arguments an the class and method name: 我想编写一个简单的Logger-Tool,它使用传递的参数报告方法的进入和离开,以及类和方法名称:

The log file I'm aiming at: 我的目标是:

ENTERING: ClassOfDoom::MethodOfDoom( arg1={1} [int], arg2={true} [bool] )
LEAVING: ClassOfDoom::MethodOfDoom RETURNING 1 [int]

The code I have in mind: 我想到的代码:

class ClassOfDoom {
  // Remeber: MethodOfDoom is a _random_ method with _random_ arguments
  public int MethodOfDoom(int arg1, bool arg2) {
    Log.Entering(this, this.MethodOfDoom, arg1, arg2);
    ...
    return Log.Returing(this, this.MethodOfDoom, 1);
  }
}

Is there a way to achieve this? 有没有办法实现这个目标? Or isn't C# as flexible as that? 或者C#不是那么灵活吗?

Thanks in advance! 提前致谢!

You can make your logging function take a MethodBase argument and use MethodBase.GetCurrentMethod to pass the current method info as an argument. 您可以使您的日志记录函数采用MethodBase参数,并使用MethodBase.GetCurrentMethod将当前方法信息作为参数传递。

Then, in the logger, you could check its properties Name and DeclaringType to get the method information. 然后,在记录器中,您可以检查其属性NameDeclaringType以获取方法信息。 Also, passing parameters is easy by declaring a params object[] args parameter in the logging function: 此外,通过在日志记录函数中声明params object[] args参数,可以轻松传递参数:

public static void Entering(object obj, MethodBase methodInfo,
                            params object[] args) {
    Console.WriteLine("ENTERING {0}:{1}", methodInfo.DeclaringType.Name,
                                          methodInfo.Name);
    ...
}

I'm not sure I entirely understand your question, but if you are trying to make a call to Log.Entering and Log.Returning inside an arbitrary (random) method and using the method's actual parameters, you should check out PostSharp . 我不确定我是否完全理解你的问题,但如果你试图在任意(随机)方法中调用Log.Entering和Log.Returning并使用方法的实际参数,你应该检查PostSharp It will allow you to inject code in a method body and then do some work based on the reflected method information you get from the .NET framework (and the actual parameters passed to the method at runtime). 它允许您在方法体中注入代码,然后根据从.NET框架获得的反射方法信息(以及在运行时传递给方法的实际参数)执行一些工作。

You could do it with Expression easily enough - it would look something like: 您可以使用Expression轻松完成它 - 它看起来像:

Log.Capture(() => this.MethodOfDoom(arg1, arg2));

Here's an example; 这是一个例子; I've been a bit lazy using Compile().DynamicInvoke() to read the arg-values - for real code I'd try to read it more directly: 我一直懒得使用Compile().DynamicInvoke()来读取arg值 - 对于真正的代码我会尝试更直接地读取它:

using System;
using System.Diagnostics;
using System.Linq.Expressions;
class Program
{
    DateTime MethodOfDoom(string s, int i)
    {
        return DateTime.Today;
    }
    public void RunTest()
    {
        int i =123;
        Log.Capture(() => this.MethodOfDoom("abc", i));
    }
    static void Main()
    {
        new Program().RunTest();
    }
}
static class Log
{
    public static T Capture<T>(Expression<Func<T>> method)
    {   
        MethodCallExpression mce = method.Body as MethodCallExpression;
        if (mce == null) throw new InvalidOperationException(
             "Method-call expected");
        string name = mce.Method.Name;
        try
        {
            int i = 0;
            foreach(var param in mce.Method.GetParameters())
            {
                object argValue = Expression.Lambda(mce.Arguments[i++])
                        .Compile().DynamicInvoke();
                Trace.WriteLine(param.Name + "=" + argValue, name);
            }
            Trace.WriteLine("ENTERING", name);
            T result = method.Compile().Invoke();
            Trace.WriteLine("EXITING: " + result, name);
            return result;
        }
        catch (Exception ex)
        {
            Trace.WriteLine("EXCEPTION: " + ex, name);
            throw;
        }
    }
}

If widely used in your code, this scenario is best implemented using Aspect Oriented Programming (AOP) techniques. 如果在代码中广泛使用,则最好使用面向方面编程(AOP)技术实现此方案。 There are different frameworks that can be used (such as Spring.NET AOP), which you can use in your .NET application. 可以使用不同的框架(例如Spring.NET AOP),您可以在.NET应用程序中使用它们。 Here is a reference article that might help you get started: 这是一篇可能有助于您入门的参考文章:

http://www.developer.com/lang/article.php/10924_3795031_2 http://www.developer.com/lang/article.php/10924_3795031_2

The referenced article gives you the logging enter/exit scenario as an example. 引用的文章为您提供了日志记录输入/退出方案作为示例。

我之前使用PostSharp来做这件事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM