| Severity | Error |
| Reported by | Metalama.Patterns.Observability |
| Message | The '<Member>' <Kind> is 'new'. This is not supported by the [Observable] aspect. |
Cause
The [Observable] aspect raises the PropertyChanged event by property name. When a derived class declares a field or property with the new modifier, the derived member and the hidden base member share the same name, so a notification can't tell which one changed. For this reason, the aspect doesn't support members declared with new.
Metalama reports LAMA5155 for each field or property declared with the new modifier in a type to which the [Observable] aspect applies. Remember that the aspect is inherited: it also applies to the classes derived from a class marked with [Observable]. In the message, <Kind> is the kind of declaration (field or property) and <Member> is its name.
In the following example, DiscountedProduct inherits the aspect from Product and hides its Price property.
1using Metalama.Patterns.Observability;
2
3namespace Doc.LAMA5155.Error;
4
5[Observable]
6public partial class Product
7{
8 public decimal Price { get; set; }
9}
10
11// The [Observable] aspect is inherited from Product.
12public partial class DiscountedProduct : Product
13{
14 // Error: the property hides the Price property of the base class.
Error LAMA5155: The 'DiscountedProduct.Price' property is 'new'. This is not supported by the [Observable] aspect.
15 public new decimal Price { get; set; }
16}
17
Resolution
Remove the new modifier by giving the member its own name, as in the following example. If the derived class only needs to change the value stored in the base property, use the base property instead of declaring a new one.
1using Metalama.Patterns.Observability;
2
3namespace Doc.LAMA5155.Fixed;
4
5[Observable]
6public partial class Product
7{
8 public decimal Price { get; set; }
9}
10
11// The [Observable] aspect is inherited from Product.
12public partial class DiscountedProduct : Product
13{
14 // Fixed: the property has its own name instead of hiding Price.
15 public decimal DiscountedPrice { get; set; }
16}
17
1using System.ComponentModel;
2using Metalama.Patterns.Observability;
3
4namespace Doc.LAMA5155.Fixed;
5
6[Observable]
7public partial class Product : INotifyPropertyChanged
8{
9 private decimal _price;
10
11 public decimal Price
12 {
13 get
14 {
15 return _price;
16 }
17
18 set
19 {
20 if (_price != value)
21 {
22 _price = value;
23 OnPropertyChanged("Price");
24 }
25 }
26 }
27
28 protected virtual void OnPropertyChanged(string propertyName)
29 {
30 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
31 }
32
33 public event PropertyChangedEventHandler? PropertyChanged;
34}
35
36// The [Observable] aspect is inherited from Product.
37public partial class DiscountedProduct : Product
38{
39 private decimal _discountedPrice;
40
41 // Fixed: the property has its own name instead of hiding Price.
42 public decimal DiscountedPrice
43 {
44 get
45 {
46 return _discountedPrice;
47 }
48
49 set
50 {
51 if (_discountedPrice != value)
52 {
53 _discountedPrice = value;
54 OnPropertyChanged("DiscountedPrice");
55 }
56 }
57 }
58
59 protected override void OnPropertyChanged(string propertyName)
60 {
61 base.OnPropertyChanged(propertyName);
62 }
63}
64