c# - 从扩展方法中获取原始变量名

标签 c# reflection extension-methods

我们目前正在开发一个日志记录解决方案,并且已经实现了一个名为“Log”的扩展方法。在写入日志文件时,我们希望写入原始变量名(而不是扩展方法中使用的变量名)。

我们目前要做的是:

public void DoSomeWork()
{
    String testString = "Hey look I'm a string!";
    testString.Log("testString value");
}

用扩展方法:

public static String Log(this String valueToStore, String name)
{
    // The logging code which uses the 'name' parameter
}

这里的问题是,阅读较长的代码行会变得困难,而且看起来是簇状的。什么是理想的是:

public void DoSomeWork()
{
    String testString = "Hey look I'm a string!";
    testString.Log();
}

使用扩展方法:

public static String Log(this String valueToStore)
{
    // The logging code which is able to retrieve the 
    // value 'testString' from the 'valueToStore' value
}

这完全可以通过使用反射来实现吗?我知道 nameof 选项,但它仅在扩展方法中使用时返回字符串“valueToStore”。

最佳答案

嗯,简短的回答是否定的。不保证变量名在编译后以不变的形式保留。该信息必须以某种方式持久化(例如通过使用 nameof())。此外,变量名称可能不存在 ("test".GetVarName())。

长答案是:是的,可能,但这是我一生中创造的最荒谬的事情之一:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
            var myVarName = "test";
            myVarName.Test();
            Console.ReadKey();
        }
    }

    static class Extensions
    {
        public static void Test(
            this string str,
            [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
            [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
            [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0
        )
        {
            var relevantLine = File.ReadAllLines(sourceFilePath)[sourceLineNumber-1];
            var currMethodName = MethodInfo.GetCurrentMethod().Name;
            var callIndex = relevantLine.IndexOf(currMethodName + "()");
            var sb = new Stack<char>();

            for (var i = callIndex - 2; i >= 0; --i)
            {
                if (Char.IsLetterOrDigit(relevantLine[i]))
                {
                    sb.Push(relevantLine[i]);
                }
            }

            Console.WriteLine(new String(sb.ToArray()));
        }
    }
}

关于c# - 从扩展方法中获取原始变量名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38747544/

相关文章:

c# - nHibernate 的通用存储库

reflection - Dart虚拟机不保证变量不能是变量但可能是函数?

c# - 静态类的扩展方法?

.net - 扩展方法是将函数添加到枚举的唯一方法吗?

typescript - 扩展 Typescript 索引对象以一般访问索引对象(字典)值的类型

c# - SslStream 身份验证在本地系统帐户下失败

c# - 在 .net 中循环遍历 xml

c# - Reflection.Typeinfo/Reflection.Type 没有 GetProperties/GetFields 方法

C# Assembly.Load 与 Assembly.ReflectionOnlyLoad

c# - WebApi 2.0 路由与查询参数不匹配?