Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以通过函数传递参数属性吗?_C#_Logging - Fatal编程技术网

C# 我可以通过函数传递参数属性吗?

C# 我可以通过函数传递参数属性吗?,c#,logging,C#,Logging,奇怪而又非常具体的问题。现在我们有一个日志接口,它使用CallerMemberNameAttribute如下所示: interface ILogger { void Info(string message, [CallerMemberName] string memberName = ""); } 这一切都是伟大而完美的,在我们的实施中效果很好。但是,出现了一个需求,即我们需要编写一些可以在流程中调用的函数,以及其他地方调用的函数,并且这些函数需要使用定义的ITracer类,该类如下所

奇怪而又非常具体的问题。现在我们有一个日志接口,它使用
CallerMemberNameAttribute
如下所示:

interface ILogger
{
    void Info(string message, [CallerMemberName] string memberName = "");
}
这一切都是伟大而完美的,在我们的实施中效果很好。但是,出现了一个需求,即我们需要编写一些可以在流程中调用的函数,以及其他地方调用的函数,并且这些函数需要使用定义的
ITracer
类,该类如下所示:

interface ITracer
{
    void TraceInformation(string message);
}
因此,当在我们的环境中运行时,这些函数应该登录到我们当前的日志infra,但当在其他环境中运行时,它有自己的
ITracer
集来完成自己的事情。因此,我编写了一个垫片,在我们的环境中调用时只传递消息:

class Logger : ILogger
{
    public void Info(string message, [CallerMemberName] string memberName = "") => // log some stuff

    public ITracer GetTraceWriter() => return new TraceWriter(this);
}

class TraceWriter : ITracer
{
    public TraceWriter(ILogger logger) => this.logger = logger;

    public void TraceInformation(string message) => this.logger.Info($"{message}");
}
这可以正常工作,但是
memberName
是输出的日志消息的一部分,在这种实现中,当TraceWriter开始记录时,它的
memberName
始终等于
TraceInformation
。有没有办法通过函数调用传递这个参数属性?这里的主要问题是我无法更改
ITracer
接口

已考虑但无法实施的解决方案:

  • 更改
    TraceInformation
    调用
    ITracer
    以返回对
    ILogger.Info
    的函数调用,该函数调用可以直接从方法调用(无法执行此操作,因为我无法更改ITracer接口)

您可以做的一件事,可能是,也可能不是理想的,就是使用类来查找调用函数的堆栈

您可以使用它在堆栈中进行迭代,以查找(或排除)特定类型,或者可能是实现特定接口的类型,或者更简单地说,只是“向上”堆栈特定数量的帧

如果您在
void Info(…)
的实现中包含了这个选项,那么您可以按如下方式访问方法名称:

# get the name of the current method (i.e. Info)
new StackFrame(0, false).GetMethod().Name

# get the name of the calling method (i.e. TraceInformation)
new StackFrame(1, false).GetMethod().Name

# get the name of the parent calling method - what you are looking for 
new StackFrame(2, false).GetMethod().Name
当然,在从
ITracer
对象调用方法和直接调用方法时,您需要进行协调。您还可以获取调用对象,检查它们实现的接口,并记录适当的方法名

这都使用反射,所以您需要考虑性能影响,但是我希望<>代码> CaleReMeNeNeN/CODE>也使用反射/可能有类似的影响。