0

The code at the bottom of this post is the simplified version of what I use in our console application to implement INotifyPropertyChanged pattern and track which properties of a class have been changed, means have assigned a new value.

You can copy and paste the code into visual studio and see It is working fine.

However, I really don't like passing strings to the method HasPropertyChanged. You can pass "whateverString" as a property name, and the application compiles. I am looking for a technique that forces the caller to pass only one of the class properties at compile time. Can I do that?

Please note:

  • I know I can use enums, but I am looking for a general technique that I can easily apply to all business classes. Add an enum to each class with names same as property names is not an option for our application.
  • I know I can use nameof operator to pass the property name to the class, however, still, the caller can pass "whateverString" as the parameter. I like avoid using string


class Program
{
    static void Main(string[] args)
    {
        DemoCustomer dc = new DemoCustomer();
        dc.CustomerName = "Test Customer";
        Console.WriteLine(dc.IsPropertyChanged("CustomerName"));
        Console.WriteLine(dc.IsPropertyChanged("PhoneNumber"));
        Console.ReadKey();
    }

    public class DemoCustomer : INotifyPropertyChanged
    {
        private Guid idValue = Guid.NewGuid();
        private string customerNameValue = String.Empty;
        private string phoneNumberValue = String.Empty;

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public DemoCustomer()
        {
            PropertyChanged += DemoCustomer_PropertyChanged;
        }

        private Dictionary<String, bool> changedProperties = new Dictionary<string, bool>();

        private void DemoCustomer_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            changedProperties[e.PropertyName] = true;
        }

        public bool IsPropertyChanged(string propertyName)
        {
            return changedProperties.ContainsKey(propertyName);
        }

        public Guid ID
        {
            get
            {
                return this.idValue;
            }
        }

        public string CustomerName
        {
            get
            {
                return this.customerNameValue;
            }

            set
            {
                if (value != this.customerNameValue)
                {
                    this.customerNameValue = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public string PhoneNumber
        {
            get
            {
                return this.phoneNumberValue;
            }

            set
            {
                if (value != this.phoneNumberValue)
                {
                    this.phoneNumberValue = value;
                    NotifyPropertyChanged();
                }
            }
        }
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
Allan Xu
  • 7,998
  • 11
  • 51
  • 122
  • 2
    You are looking for expression trees – Alexei Levenkov Feb 04 '18 at 04:46
  • 1
    https://stackoverflow.com/questions/1128091/is-there-a-good-strongly-typed-way-to-do-propertychanged-events-in-c – CodingYoshi Feb 04 '18 at 04:47
  • Eventually you will need to use string as that is what the event arg needs. In your base class you could simple not expose a method that uses string and instead use lambda expression as already suggested in a previous comment. – Nkosi Feb 04 '18 at 04:58
  • 1
    I don't get what's your problem with the current solution: `[CallerMemberName]` fills the name for you "automagically", you don't really have a problem unless you wish to create one by passing an incorrect parameter to an argument that you shouldn't even pass to begin with. – Sergey Kalinichenko Feb 04 '18 at 05:05
  • @dasblinkenlight: I would be careful with the statement "you don't really have a problem unless you wish to create one by ..." . So many bugs and defects are created with passing invalid parameters. I am trying to avoid keep guarding invalid param at runtime. I like to use the compiler as my test platform where possible. Similar to what we do with enums. – Allan Xu Feb 04 '18 at 07:33

0 Answers0