| Severity | Error |
| Reported by | PostSharp.Patterns.Model |
| Message | Method <Method> contains parameters of non-intrinsic type. The [Pure] attribute can be applied only to methods with parameters of intrinsic types such as int or string. |
Cause
The PureAttribute attribute tells the NotifyPropertyChangedAttribute aspect that the result of a method depends only on its arguments, so that a property getter can call the method without the aspect analyzing it. The property then depends on the arguments of the call. This only holds when the arguments cannot change without being passed again, so PostSharp reports DOM004 when a pure method has a parameter of another type than:
- a primitive type,
string,decimal,DateTime, an enum, or another value type of theSystemnamespace; - an array of these types;
object, in which case the aspect assumes that the objects passed are immutable, and does not track their changes.
PostSharp checks every method marked with the attribute, also when you apply the attribute to a class, a struct or an assembly. It reports the message on the method.
In the following example, the pure method ComputeTotal receives the whole Invoice, whose properties can change after the call.
using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;
namespace Errors.DOM004_Error;
public static class PriceCalculator
{
// The invoice can change between two calls, so the result does not depend only on the arguments.
[Pure]
public static decimal ComputeTotal( Invoice invoice ) => invoice.Subtotal + invoice.Shipping;
}
[NotifyPropertyChanged]
public class Invoice
{
public decimal Subtotal { get; set; }
public decimal Shipping { get; set; }
public decimal Total => PriceCalculator.ComputeTotal( this );
}
public static class Program
{
public static void Main()
{
Invoice invoice = new();
((INotifyPropertyChanged) invoice).PropertyChanged += ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );
invoice.Subtotal = 100;
invoice.Shipping = 5;
Console.WriteLine( $"Total: {invoice.Total}" );
}
}
error DOM004: DOM004_Error.cs(11,27): Method Errors.DOM004_Error.PriceCalculator.ComputeTotal contains parameters of non-intrinsic type. The [Pure] attribute can be applied only to methods with parameters of intrinsic types such as int or string.
Resolution
- Pass the values that the method needs, of immutable types, instead of the object that holds them. The property then depends on each of these values.
- When the method depends on the state of an object, remove the PureAttribute attribute, and move the logic into a method of the class of the property, which the aspect analyzes.
In the following example, ComputeTotal receives the subtotal and the shipping cost, and the aspect notifies Total when either of them changes.
using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;
namespace Errors.DOM004_Fixed;
public static class PriceCalculator
{
// The method receives the values it needs, which are of intrinsic types.
[Pure]
public static decimal ComputeTotal( decimal subtotal, decimal shipping ) => subtotal + shipping;
}
[NotifyPropertyChanged]
public class Invoice
{
public decimal Subtotal { get; set; }
public decimal Shipping { get; set; }
public decimal Total => PriceCalculator.ComputeTotal( this.Subtotal, this.Shipping );
}
public static class Program
{
public static void Main()
{
Invoice invoice = new();
((INotifyPropertyChanged) invoice).PropertyChanged += ( _, e ) => Console.WriteLine( $"PropertyChanged: {e.PropertyName}" );
invoice.Subtotal = 100;
invoice.Shipping = 5;
Console.WriteLine( $"Total: {invoice.Total}" );
}
}
PropertyChanged: Subtotal
PropertyChanged: Total
PropertyChanged: Shipping
PropertyChanged: Total
Total: 105
See Also
Reference
PureAttribute
NotifyPropertyChangedAttribute
Other Resources