Open sandboxFocusImprove this doc

DOM025: Property Depends on a Variable Assigned in a Try Statement

Severity Error
Reported by PostSharp.Patterns.Model
Message NotifyPropertyChangedAttribute: automatic analysis of property <Property> failed. Method <Method> depends on a variable that is assigned inside a try statement. This is not currently supported. To ignore this message, add the [SafeForDependencyAnalysis] attribute to the property <Property>, and call Depends.On to specify its dependencies explicitly.

Cause

The NotifyPropertyChangedAttribute aspect analyzes the getter of each property, and the methods of the same class that it calls, to find what the property depends on. When the code reads a local variable, the analysis follows the assignments of this variable. It does not support an assignment that is inside a try statement, in the try block or in one of its catch or finally blocks.

PostSharp reports DOM025 on <Property> when <Method>, the getter or a method that it calls, reads a local variable that is assigned inside a try statement.

In the following example, the AverageLine property calls ComputeAverageLine, which assigns result in a try statement to handle a division by zero.

using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;

namespace Errors.DOM025_Error;

[NotifyPropertyChanged]
public class Invoice
{
    public int Total { get; set; }

    public int LineCount { get; set; }

    // The getter calls a method that assigns a variable in a try block.
    public int AverageLine => this.ComputeAverageLine();

    private int ComputeAverageLine()
    {
        int result;

        try
        {
            result = this.Total / this.LineCount;
        }
        catch ( DivideByZeroException )
        {
            result = 0;
        }

        return result;
    }
}

public static class Program
{
    public static void Main()
    {
        var invoice = new Invoice();
        ((INotifyPropertyChanged) invoice).PropertyChanged +=
            ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );

        invoice.Total = 120;
        invoice.LineCount = 3;
        Console.WriteLine( $"AverageLine: {invoice.AverageLine}" );
    }
}
error DOM025: DOM025_Error.cs(15,16): NotifyPropertyChangedAttribute: automatic analysis of property Errors.DOM025_Error.Invoice.AverageLine failed. Method Errors.DOM025_Error.Invoice.ComputeAverageLine depends on a variable that is assigned inside a try statement. This is not currently supported. To ignore this message, add the [SafeForDependencyAnalysis] attribute to the property Errors.DOM025_Error.Invoice.AverageLine, and call Depends.On to specify its dependencies explicitly.

Resolution

  • Remove the try statement from the getter and from the methods that it calls, for example by testing that a divisor is not zero instead of catching the exception.
  • Otherwise, add SafeForDependencyAnalysisAttribute to the property, and call On in its getter with the properties that it depends on. The attribute makes you responsible for the dependencies that the analysis does not find.

In the following example, AverageLine declares its dependencies on Total and LineCount, so the aspect notifies it when either changes.

using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;

namespace Errors.DOM025_Fixed;

[NotifyPropertyChanged]
public class Invoice
{
    public int Total { get; set; }

    public int LineCount { get; set; }

    // The property declares its dependencies itself.
    [SafeForDependencyAnalysis]
    public int AverageLine
    {
        get
        {
            Depends.On( this.Total, this.LineCount );

            return this.ComputeAverageLine();
        }
    }

    private int ComputeAverageLine()
    {
        int result;

        try
        {
            result = this.Total / this.LineCount;
        }
        catch ( DivideByZeroException )
        {
            result = 0;
        }

        return result;
    }
}

public static class Program
{
    public static void Main()
    {
        var invoice = new Invoice();
        ((INotifyPropertyChanged) invoice).PropertyChanged +=
            ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );

        invoice.Total = 120;
        invoice.LineCount = 3;
        Console.WriteLine( $"AverageLine: {invoice.AverageLine}" );
    }
}
PropertyChanged: Total
PropertyChanged: AverageLine
PropertyChanged: LineCount
PropertyChanged: AverageLine
AverageLine: 40

See Also

Reference

NotifyPropertyChangedAttribute
SafeForDependencyAnalysisAttribute
On

Other Resources

Handling Corner Cases of the NotifyPropertyChanged Aspect