【问题标题】:If I throw an exception in a getter of a property, can I obtain the name of the property in a catch block?如果我在属性的 getter 中抛出异常,我可以在 catch 块中获取属性的名称吗?
【发布时间】:2011-11-02 19:18:54
【问题描述】:

如果我从一个属性的getter中抛出一个异常,是否有可能获得

我在其中调用该属性的 catch 块中的属性——例如使用反射或

读取堆栈跟踪?

例如:

class Animal
{
  private string _name;
  public string Name {

           get { throw new Exception(); } 

           set { _name = value; }
                     }
}

在另一个地方,我调用 Name 属性的 getter,我想在 catch 块中获取属性名称:

Animal cat = new Animal();

try{ 
    string catName = cat.Name;
   }

catch (Exception e)
   {

    string propertyName = //Here I should be able to reach "Name"  

   }

【问题讨论】:

  • 不要在属性的 getter 中抛出异常。
  • 重点是什么,你想做什么,为什么?
  • 我也想知道你为什么认为你需要这个。如果你需要这个,我敢打赌你的设计有问题。
  • 我希望它用于错误记录目的!

标签: c# .net reflection exception-handling stack-trace


【解决方案1】:

它将在您的堆栈跟踪中显示为 get_Name() 方法中的异常。您可能可以解析它以获取属性名称

【讨论】:

  • 能否请您详细说明问题中的示例?
  • 查看@Mongus 答案。编译后您的属性将更改为get_'PropertyName(基本上是getter 和setter 方法)。
【解决方案2】:

您可以使用正则表达式解析e.StackTrace

    try
    {
            int x = this.Ong;
    }
    catch ( Exception ex )
    {
            Console.WriteLine ( Regex.Match ( ex.StackTrace, @"get_(?<prop>.*)\(\)" ).Groups["prop"].Value );
    }

注意您应该对上面的正则表达式进行更多错误检查,因为如果不是从属性引发异常,Groups["prop"] 可能为 null。

【讨论】:

    【解决方案3】:

    有两个选项,没有一个很好:

    1. 如 Ashley 和 Mongus 所述,从 Exception.StackTrace 属性解析 get_Name() 方法。当 getter 被内联时,这将失败(这不太可能发生),因为内联方法调用(显然)不会显示在堆栈跟踪中。

    2. 抛出包含该属性名称的特殊异常:

      public string PropertyName
      {
          get { throw new PropertyException("PropertyName", "Ex message.");
      } 
      

      但这也不是很好,因为您应该明确地抛出这种类型的异常。因此,调用堆栈深处的故障必须包含在 PropertyException 中。

    【讨论】:

      【解决方案4】:

      如果您正在考虑这样的事情,您很可能最好实现类似 INotifyPropertyChanged 的东西并将其作为您的 getter 的一部分,而不是像正常使用一样只关心 setter。

      How to: Implement the INotifyPropertyChanged Interface

      【讨论】:

        【解决方案5】:

        【讨论】:

          【解决方案6】:

          从 C# 5 开始,您可以使用CallerMemberNameAttribute

          public class SomeCustomException : Exception
          {
              public string PropertyName { get; }
          
              public SomeCustomException(string propertyName) 
                  : base($"Property {propertyName} was null)
              {
                  this.PropertyName = propertyName;
              }
          }
          
          public class Animal
          {
              public string Name
              {
                  get { Throw(); }
              }
          
              private static void Throw([CallerMemberName] string propertyName = null)
              {
                  // propertyName will be 'Name'
                  throw new CustomException(propertyName);
              }
          }
          

          我本可以将[CallerMemberName] 直接放在SomeCustomException 的构造函数上,但这似乎不必要地难看:异常不需要知道它将从属性getter 中调用,因此单独的静态Throw方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-07-28
            • 1970-01-01
            • 2019-06-05
            • 1970-01-01
            • 2011-05-20
            • 1970-01-01
            • 2014-08-17
            • 2013-05-29
            相关资源
            最近更新 更多