With MVVM I always see these both methods for properties:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
NotifyPropertyChanged("MyProperty");
}
}
and
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
NotifyPropertyChanged(m => m.MyProperty);
}
}
The first one use an hardcoded string to NotifyPropertyChanged and the second one use a lambda expression to NotifyPropertyChanged. I don't want to create a debate to ask what is the better solution but I would like to understand what are the differences bewteeen these two solution. What are the consequences of using one or the other?
Correct me if I'm wrong but the lambda expression solution should use more memory and should be slower than the hardcoded string because the NotifyPropertyChanged method of the base class use delegate and reflection. But the hardcoded string solution may create stupid bug because it's a string and nothing to tell me I correctly wrote it.
The second expression would either generate a compiler error on the property name change, or would automatically change with it (via the Rename support in VS or ReSharper).
So basically, you gain compiler support for property names. The wrong name provided to the notify would mean that data-binding would break. With string names, this breakage would be silent.
In a small UI the choice is irrelevant in my opinion, but in a large application with a heavy UI layer the extra support against bugs can pay itself off in the long run.
Performance won't be problematically slower, don't forget, binding is reflection-powered anyway. Performance, as always, is relative. The hard-coded version will technically be faster because it doesn't need to reflect the property name out of the meta-data. How much faster, I'm not sure.
Rather than repeating that code of NotifyPropertyChanged for every property, I felt the below code is more cleaner
Create a Set method in your ViewModel Base
protected bool Set<T>(Expression<Func<T>> selectorExpression, ref T field, T value)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
RaisePropertyChanged(selectorExpression);
return true;
}
and use them as
string title;
public string Title
{
get { return title; }
set { Set(() => Title, ref title, value); }
}
I use the following method in a base class implementing INotifyPropertyChanged and it is so easy and convenient:
public void NotifyPropertyChanged()
{
StackTrace stackTrace = new StackTrace();
MethodBase method = stackTrace.GetFrame(1).GetMethod();
if (!(method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
{
throw new InvalidOperationException("The NotifyPropertyChanged() method can only be used from inside a property");
}
string propertyName = method.Name.Substring(4);
RaisePropertyChanged(propertyName);
}
Related
I've looked around a bit online and wasn't able to easily find a solution to what i was looking for. It may be in part to me not being sure the terminology to search for.
I wanted to know is there a way to call the PropertyChanged event using the property member name like so...
private string height;
public string Height
{
get { return name; }
set
{
Set(ref height, value);
RaisePropertyChanged( ()=> Name);
}
}
rather than using the actual string which can be seen here..
private string height;
public string Height
{
get { return name; }
set
{
Set(ref height, value);
RaisePropertyChanged("Name");
}
}
Raise Event
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
I've attempted a solution to this, but wasn't able to come to a conclusion. I know there are methods out there somewhere and im sure there are more modern ways to do this. Its 2016!!
Since you appear to be using C# 6, you can use the nameof operator, which resolves the name of the referenced property at compile time, passing a string to your method.
RaisePropertyChanged(nameof(Name));
If you need to use an earlier C# compiler, you can resolve the name of the property through a lambda expression; this is what Entity Framework does for its Include operator. You can define a GetPropertyName utility method (see example), then call it like so:
RaisePropertyChanged(GetPropertyName(() => Name));
I am working with some existing code and trying to figure out the advantage (if any) of using a string constant for the name of a property when implementing INotifyPropertyChanged interface.
So for example doing this:
/*
* Why use this instead of string literal
* in OnPropertyChanged below??
*/
public const string CustomerIdPropertyName = "CustomerId";
private int _customerId;
public int CustomerId
{
get
{
return _customerId;
}
set
{
if (_cusomterId != value)
{
_customerId = value;
OnPropertyChanged(CustomerIdPropertyName);
}
}
}
Instead of this:
private int _customerId;
public int CustomerId
{
get
{
return _customerId;
}
set
{
if (_cusomterId != value)
{
_customerId = value;
OnPropertyChanged("CustomerId");
}
}
}
Both versions are equally prone to typing errors.
If you have a somewhat recent version of .NET, your property changed handler should look like this:
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Then your property looks like this:
private int _customerId;
public int CustomerId
{
get
{
return _customerId;
}
set
{
if (_cusomterId != value)
{
_customerId = value;
this.OnPropertyChanged();
}
}
}
And you don't have any trouble with typing errors.
There isn't an advantage compiler wise, since both will end up being a constant value.
I can't imagine a real advantage in using the code like that way. Either ways it is easy to make a typo, and you are not going to reuse that constant for anything, so it is pointless.
I had love to see the new nameof keyword implement in the next version of .NET. Or even better, if possible, use [CallerMemberName] as Marc Gravell suggested.
The use of nameof will be useful when having custom calculated properties (like in WPF for example) that don't have their own getter / setter.
To answer your question (trying to figure out the advantage) : there is an advantage for an observer who know your type and wait for a specific property to change
void Observe(Customer c)
{
c.PropertyChanged += (s, e) =>
{
if (e.PropertyName == Customer.CustomerIdPropertyName)
{
MessageBox.Show("New id " + Customer.CustomerId);
}
}
}
If you want to go futher :
Typing errors can be avoided using a property selector expression to fill your CustomerIdPropertyName.
You won't need it with nameof keyword (CTP). If you don't have this kind of observer, CalleMemberNameAttribute is the easiest way.
I imagine it is just to avoid bugs caused by typos and try and make the code a little easier to read. Also if you change the name of the property it means changing the value of the const will then work for all code that is checking if the property has changed. e.g. imagine this code:
public void Main()
{
var obj = new ClassWithNotifier();
obj.OnPropertyChanged += ObjectPropertyChanged;
DoSomethingWithObj(obj);
}
private void ObjectPropertyChanged(string propertyName)
{
switch (propertyName) {
case ClassWithNotifier.CustomerIdPropertyName:
// If the constant changes this will still work
break;
case "SomeOtherPropertyName":
// If you change the property string that is passed here from
// your class ClassWithNotifier then this will now break
break;
}
}
In the example above, regardless of the value of the constant the code will work, and if you want to change the property name at some point then you only need to change the constant value and everything will still work with out having to find everywhere we are checking for the name (obviously if you want to change the name of the constant variable as well then you still need to find those references, but finding references to Public fields is easier than searching through the whole project for magic strings)
This can be applied to many different languages, but I am specifically working with C# and INotifyPropertyChanged.
If a property is set, should I re-assign its value even if it did not change?
For example:
public int IntProperty
...
set
{
var oldValue = _intProperty;
_intProperty = value;
if (!Equals(value, oldValue))
{
OnPropertyChanged(...);
}
}
vs.
public int IntProperty
...
set
{
if (!Equals(value, _intProperty))
{
_intProperty = value;
OnPropertyChanged(...);
}
}
I just can't decide. Technically, it shouldn't make a difference, but there are some odd corner cases (like strange Equals implementations that should never happen) that could change the behavior.
This can be influenced by the type of the property. Some classes have intelligent Equals methods, and some don't. If you trust yours, it shouldn't matter, but if the class doesn't override Equals, or doesn't do it well, then it changes things. On the whole, I'd say that the underlying value shouldn't change without the notification being sent, so I'd go with #2.
To give an example, maybe there's a simple data holder looking something like this:
class Data
{
public int ID { get; set; }
public string SomeData { get; set; }
public string SomeOtherData { get; set; }
//Assume there are lots of other fields here
public override bool Equals(object obj)
{
Data other = obj as Data;
if (other != null)
{
return ID == other.ID;
}
return false;
}
}
Now if ID is supposed to be unique (possibly because it maps to a DB ID value) then this isn't that bad of an idea, but it doesn't stop people from going around creating objects with the same ID and different data values. If some mean person did that you could end up setting a value to a property such as your in which the new value really is significantly different, but .Equals will say they are the same. Now no matter what happens here you're somewhat screwed, but which is worse, not setting a value that shouldn't be different but is (because the set is inside the if) or changing the value and not notifying event subscribers that the event changed? (You also have the third option of setting the event and notifying people even if it changed, possibly indicated that this is the case via the event args.) If an event subscriber is code that persists the change to the database (which is often the case with this type of structure) then you're changing a value in memory, thinking that it really changed (getting it back out is an exact reference match), but the value still won't be persisted because the event wasn't fired.
Sorry for the wall of text.
tl;dr version, users of this code can find a way to screw you no matter what you do; eventually you need a minimal amount of trust in them for your code to be effective.
It has no use setting it again, it only takes time/saves performance.
And since already the notification is inside the if statement, it also is not more code.
If you're going to do the check either way then I'd say not to worry about setting the value if they are equal. Save yourself the cycle.
Short answer - generally, either check if they are different and set it only if it is, or don't bother checking.
Longer answer - For MVVM, one accepted practice is to abstract the set to a base class, where you have two overloads of a function to set the property. This should handle all cases of setting the property, makes them easier to implement in your inherited classes, and cleans things up.
public event PropertyChangedEventHandler PropertyChanged;
public Boolean SetProperty<T>(string propertyName, ref T field, T value, IEqualityComparer<T> comparer)
{
if (!comparer.Equals(field, value))
{
T oldValue = field;
field = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
public Boolean SetProperty<T>(string propertyName, ref T field, T value)
{
return SetProperty(propertyName, ref field, value, EqualityComparer<T>.Default);
}
Then, in your ViewModel, you would do something like this:
private int mMyIntProperty = 0;
public string MyIntProperty
{
get { return mMyIntProperty; }
set { SetProperty("MyIntProperty", ref mMyIntProperty, value); }
}
For simple types, you don't need to specify a Comparer, as the default will do just fine. However, having the comparer available makes checking complex types easier.
Is there any difference between the two pieces of code below? Or is the top just a short form of the bottom one?
public string Name { get; set; }
and
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
The only difference (other than the fact you would have to do the initialization with "Default Name" in your class constructor) is that _Name will be visible within the class itself. There's a risk that the class will internally reference _Name rather than Name, everything will work fine, and at some later point in time you'll add some logic to Name that will not be called because you're using _Name within the class.
Example:
private string _Name = "Default Name";
public string Name
{
get { return _Name.Left(42); } // Changed the getter
set { _Name = value; }
}
void MyOtherMethod()
{
string foo = _Name; // Referencing the private field accidentally instead of the public property.
// Do something with foo
}
Basic behavior and purpose of both of the property method is almost same. But the major difference is in the implementation. The difference between
public string Name{get;set;}
AND
private string _Name;
public string Name
{
get { return _Name; }
set { _Name=value; }
}
is if you use short property syntax (introduced in framework 3.0 or later), then the property sting is never initialized i.e. if you directly use "Name" property anywhere without setting the value to it, it will return a NULL value. But if you use second syntax to initialize the property value, it will return a EMPTY string because when you initialize a string, it is initialized with a EMPTY value not the NULL. So if you return the property value without initializing using FULL Property Method, it will always return the EMPTY string not the NULL value.
I dont think there is any difference in compiled code. The reason why you may want to do the full way though is if you want to add a default value (which can be done in the constructor in short hand form), or add additional code to the getter or setter
EDIT: Actually, your code is wrong it should be
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }//change here
}
not...
value = _Name;
One difference is that you can set a default on the private string when you do this
private string _Name = "Default Name";
public string Name
{
get { return _Name; }
set { value = _Name; }
}
Once compiled the two examples you showed are the same.
It is simply a short form, the underlying variable is still generated as a supporting backing field (where the data is stored,) but automatically - this is useful if you are literally just getting and setting and don't need any specific implementation details in either accessor.
For this particular implementation of second form, both are equivalent. Because the compiler will generate almost the same code if you simply write the first form.
That is, the compiler is going to add code to it:
public string Name{get;set;}
making it look like this:
private string generatedCode_Name;
public string Name
{
get { return generatedCode_Name; }
set { generatedCode_Name = value; }
}
By the way, this is incorrect
set { value = _Name; } //I believe its a typo!
I think you meant:
set { _Name = value; }
For the example as written they are an exact equivalent.
Auto-implemented properties are syntactic sugar introduced to address exactly these type of situation, where the property is used just to avoid having a public field, with no extra logic in the getter/setter. However, an auto-implemented property gives you all the benefits of properties, including metadata. Here's a rather old but still relevant link that explains a little bit more about them.
Behind the scenes, the compiler generates a backing field very similar to your own.
Can anyone clearly articulate when you use a field and when to use a property in class design?
Consider:
public string Name;
Or:
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
I realize that the second method is more proper and flexible, so that's what I try to use, generally.
But then why do I see people use the first method? Are they just lazy, or is there some specific situation where it's the correct choice? Is it just a matter of preference?
Well in C# 3.0 you can actually write:
public string Name {get; set;}
Which allows you to be proper and lazy.
Generally speaking, with properties, you get proper encapsulation. You have the choice to allow setting a value, or getting it, or both. Using a public member, you don't have that option.
It's probably one-part preference, and one-part how your team decides to handle quick and dirty class definitions, but I would say, use properties for get/sets.
To answer
Can anyone clearly articulate when you use an attribute and when to use a property in class design?
You shouldn't ever use a public attribute. You should always use a property instead. It's safer and more flexible. That said, people will be lazy, and just use a public member. However, with C# 3.0 you can use a more terse syntax to define properties, which should satisfy your inner laziness.
Simply type prop and hit <tab> to expedite the laziness in adding a property.
Just some additional information to Alan's reply:
public string Name {get; set;}
is the same as
private string _Name;
public string Name{
get { return _Name; }
set { _Name = value; }
}
If you want to disallow the set function of Name, you can have
public string Name {get; private set;}
Properties are more maintainable than fields, you can encapsulate logic in your setters/getters, allowing you to hide the implementation.
They also make refactoring easier.
More information:
Property Usage Guidelines
Field Usage Guidelines
Using properties you can control it's security:
public string Foo { protected get; private set; }
Properties gives easy way to raise events:
public string Foo
{
get { return _foo; }
}
set
{
bool cancel = false;
if(BeforeEvent != null) // EventHandler<CancelEventArgs> BeforeEvent
{
CancelEventArgs e = new CancelEventArgs();
BeforeEvent(this, e);
cancel = e.Cancel;
}
if(!cancel)
{
_foo = value;
if(AfterEvent != null) // EventHandler<EventArgs> AfterEvent
{
AfterEvent(this, new EventArgs());
}
}
}
Also I often use code like this:
string Foo
{
set
{
IsFooSet = value != null;
}
}
bool IsFooSet
{
get { return _isFoo; }
set
{
_isFoo = value;
if(value) // some event raise or controls on form change
}
}
When you make the field public, you allow the user to do whatever they want to do to the field. They can assign unexpected values, invalid values, values that can cause overflow, etc.
With the property, you have control over whether to allow the setting of new values to the field, massaging the value before storing it, notifying interested parties about the change of the field's value, etc. And the same idea for returning value through the getter. For .NET framework from 2.0 up, you can set the accessor for the getter, setter. Say, you only want the user to only have read access to the field, then you make the getter public, but the setter private or protected.
In addition to the already-given reasons for preferring properties, there's also lots of cool stuff in System.ComponentModel to do with data binding and change notification that only works with properties, rather than fields. For example, look at the documentation around PropertyChangedHandler.
A property like defined above acts like a getter and setter. The only benefits of using a property is that you can treat it like a variable with access restriction.
public string Name { get; private set; }
This property can be accessed publicly, but can only be set privately. (You wouldn't want anyone changing your name with out your consent now would you! ;) )