【问题标题】:Using Reflection to get the field/property that is being null compared?使用反射来获取比较为空的字段/属性?
【发布时间】:2012-11-21 15:50:31
【问题描述】:

我如何知道日志中最后一个为空的属性?

例如,

var a = "somevalue";
......
......
if(a == null)
{
   Log.Error(MethodBase.GetCurrentMethod().Name  + "Property : a is null");      

   //blah blah
}

就像我如何使用反射来获取当前方法名称一样,应该有一些方法可以记录最新的局部变量(或属性或字段) 那是在比较吗?顺便说一下,我使用 log4net 来记录错误。

1) 有什么方法可以做到这一点还是我们应该手动记录它?

2) 是否有任何自定义方法可以打印为空的类 -> MethodName -> Propertyname(或 FieldName)?

提前感谢您的宝贵时间。

【问题讨论】:

  • "a" 不是属性而是局部变量。
  • @fsimonazzi:感谢您的更正。问题扩展到查找局部变量/字段/属性..

标签: c# .net visual-studio-2010 .net-4.0 log4net


【解决方案1】:

正如@fsimonazzi 所提到的,“a”将是一个局部变量。

话虽如此,仍然无法检查当前的比较操作,因为在 MSIL 中没有 IF 块的正式概念 - 只有条件跳转。

如果您真的想对反射感到疯狂,您也许可以找到当前正在执行的指令并在其附近四处寻找变量,但即便如此,您也不会找到名称 - 只是一个参考 - 作为名称仅在编译之前使用。

不管怎样,反思在这里帮不了你。

请尝试使用异常 - 特别是 ArgumentNullException。这段代码将变成:

void doStuff(string param1, int param2)
{
    if (param == null)
        throw new ArgumentNullException("param1", "param1 must not be null");
    if (param2 < 0)
        throw new ArgumentOutOfRangeException("param2", "param2 should be non-negative.");

    //method body
}

然后,当您调用该方法时,您可以捕获异常并记录它——不管它是什么。

public static void Main(string[] args)
{
    try 
    {
        doStuff(null, 3);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

FxCop 等工具可以帮助确保您正确验证每个参数。


属性实际上是作为方法实现的,因此反射可以帮助您。例如,如果您正在验证一个属性并希望自动记录该位置,那么您可以。

private object _cachedObject = null;
public object CachedObject 
{
    get 
    {
        if (_cachedObject == null)
        {
            log(MethodBase.GetCurrentMethod().Name, "creating cached object");
            _cachedObject = createCachedObject();
        }
        return _cachedObject;
    }
}

.Net Framework 4.5 还带来了一个新属性,可用于替换您用于获取方法名称的 MethodBase.GetCurrentMethod().Name 构造。见[CallerMemberNameAttribute][3]

【讨论】:

  • 而且 GetCurrentMethod 一般不可靠。 stackoverflow.com/questions/8902662/…。如果您使用的是 .NET 4.5,则可以使用新的 CallerMemberAttribute msdn.microsoft.com/en-us/library/… 并将日志记录移至单独的方法,因此您不必对方法名称进行硬编码,但也不需要依赖反射.
  • 正如你所指出的,许多人说,要避免反思。无论如何,感谢您的链接。立即结帐。
  • @mitch : 检查堆栈帧并从中获取方法名好吗?
  • @nowhewhomustnotbenamed.,这不是非法或不可能的,但它可能不适合您的需求。编译器优化可能会重组您的代码,使得返回的值可能与您期望的不匹配。相对于常量字符串,反射也有点昂贵,但我不知道你的用例。如果它对您有用,并且没有引起问题,那么没关系。不过,我仍然会考虑 CallerMemberNameAttribute。
  • 感谢您的帮助米奇。会研究。
猜你喜欢
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
相关资源
最近更新 更多