Если я получу исключение в получателе свойства, могу ли я получить имя свойства в блоке перехвата? - PullRequest
3 голосов
/ 24 августа 2011

Если я выбрасываю исключение из получателя свойства, возможно ли получить имя

свойство в блоке catch, где я назвал это свойство, как при использовании отражения или

чтение трассировки стека?

Например:

class Animal
{
  private string _name;
  public string Name {

           get { throw new Exception(); } 

           set { _name = value; }
                     }
}

А в другом месте я вызываю геттер свойства Name и хочу получить имя свойства в блоке catch:

Animal cat = new Animal();

try{ 
    string catName = cat.Name;
   }

catch (Exception e)
   {

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

   }

Ответы [ 6 ]

0 голосов
/ 25 июля 2016

Начиная с 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, но это кажется излишне уродливым: исключение не должно знать, что оно будет вызвано из метода получения свойства, отсюда и отдельная статическая Throw способ.

0 голосов
/ 24 августа 2011
0 голосов
/ 24 августа 2011

Если вы рассматриваете что-то подобное, вам, скорее всего, было бы гораздо лучше реализовать что-то вроде INotifyPropertyChanged и придерживаться этого как части вашего геттера, а не заботиться только о сеттере, как при обычном использовании.

Как: реализовать интерфейс INotifyPropertyChanged

0 голосов
/ 24 августа 2011

Есть две опции, отличные от которых:

  1. Разобрать метод get_Name () из свойства Exception.StackTrace, как описывают Эшли и Монгус.Это не удастся, когда получатель будет встроен (что, скорее всего, не произойдет), потому что вызовы встроенных методов (очевидно) не будут отображаться в трассировке стека.

  2. Бросить специальное исключение, содержащееимя этого свойства:

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

    Это, однако, не так уж и велико, так как вы должны явно выдать исключение этого типа.Таким образом, ошибки из глубины стека вызовов должны быть заключены в PropertyException.

0 голосов
/ 24 августа 2011

Вы можете выполнить синтаксический анализ e.StackTrace с помощью регулярного выражения:

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

Примечание Вы должны поставить дополнительную проверку ошибок на вышеприведенное регулярное выражение, так как Groups["prop"] может быть нулевым, если исключение составляетне вырастил из собственности.

0 голосов
/ 24 августа 2011

будет отображаться в вашей трассировке стека как исключение в методе get_Name (). Вы можете, вероятно, разобрать его, чтобы получить имя свойства

...