Monday, February 29, 2016

March 2016 Speaking Engagements

I'm looking forward to another month of speaking and a bit of traveling. Be sure to stop by one of these events if you can.

Monday, March 7, 2016
LA DOT NET
Los Angeles, CA
Meetup Link
o I'll Get Back to You: Task, Await, and Asynchronous Methods

Thursday, March 17, 2016
EastBay.NET
Berkeley, CA
Meetup Link
o I'll Get Back to You: Task Await, and Asynchronous Methods

Mon-Wed, March 28-30, 2016
Code PaLOUsa
Shepherdsville, KY
Conference Website
o IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

A Look Ahead
My speaking schedule for the rest of the year is starting to fill in. This month, I was accepted to speak at KCDC in Kansas City, MO. I've heard some really great things about this event, and I'm looking forward to being a part of it in June.

Other events on my schedule include Visual Studio Live! Austin (Austin, TX) in May and NDC Oslo (Oslo, Norway) in June.

I also have proposals out for a number of other conferences and developer events. If you're interested in having me speak at your event, be sure to get in touch. My schedule is filling up fast.

Happy Coding!

My Motivation

What motivates me?

This:


Find what motivates you. Then look for reminders that you can keep handy. When you feel like you're not doing anything worthwhile, pull out one of your reminders. Then keep moving forward.

Happy Coding!

Tuesday, February 23, 2016

New Video: TDD Basics with C#

I've just published a new video on YouTube, this time taking a look at the basics of test-driven development. This starts at the very beginning and walks through the Red-Green-Refactor cycle to build up code one step at a time.

This video is great for developers who want to get started with TDD. The code we build is pretty simple: an implementation of FizzBuzz. In later videos, we'll take a look at unit testing and TDD with real-world code.
TDD Basic with C#
Test-Driven Development (TDD) lets our code develop out of our tests. We do this by following the Red-Green-Refactor cycle. In this video, we look at the basics of TDD by implementing FizzBuzz in C#. We'll be using NUnit as our testing framework, but these principles work with whatever environment we choose.
Watch the video on YouTube: TDD Basics with C#

Or watch it here:


Happy Coding!

Monday, February 22, 2016

Visual Studio Shortcuts: Implementing the Dispose Pattern

I'm a big fan of the shortcuts that Visual Studio offers to make things easier as a developer. Sometimes these simply save us some typing. But sometimes, they can help us implement a difficult pattern. In this case, Visual Studio 2015 helps us implement the Dispose pattern.

Implementing the IDisposable Interface
Using Visual Studio, we can easily implement the IDisposable interface just like we implement any other interface.

First, we'll create a class and specify that we want to implement IDisposable:


Then we can put our cursor on "IDisposable" and press "Ctrl+." (or click on the light bulb in Visual Studio 2015). This gives us a popup that offers to "Implement interface" for us:


If we chose this, the results are pretty unimpressive:


This is because the "IDisposable" interface only has a single method: "Dispose". But if we actually want to implement the Dispose pattern, things get much more complicated.

You can see how complicated by looking at various MSDN articles (IDisposable Interface and Dispose Pattern) and lots of other articles and questions on StackOverflow.

The "Implement interface" option has been around for a while, and I use it all the time. It's very useful. But it's not very useful in helping us get "IDisposable" right.

Fortunately, Visual Studio 2015 gives us a really cool option to make this easier.

Implementing the Dispose Pattern
The additional option that we get is "Implement interface with Dispose pattern":


This option is new in Visual Studio 2015 (sorry, it's not available in earlier versions of Visual Studio, but it *is* available in all editions of Visual Studio 2015, including the Community Edition).

This gives us quite a bit more code:


This takes care of most of the hard bits for us, and it gives us some really useful comments to help us get our code in the right place.

So if we need to implement the Dispose pattern in a class, we can use this option to give us the shell of the code, fill in the TODOs that we have, and then remove the elements that we don't need.

Wrap Up
Visual Studio has been one of the best IDEs out there for a long time. A big part of that is that it includes many shortcuts to make our coding faster and easier. In addition, we keep getting new, unexpected features.

Whenever I point out this particular shortcut, the response has been "I didn't know that was there!" Usually followed up with "That's really awesome!" And that was my initial reaction -- I ran across this feature completely by accident when I was implementing the IDisposable interface the hard way.

It's always good to explore our tools to see what options are out there. Sometimes we run across really cool things. In this case, we get code that helps us "fall into the pit of success" when we're implementing one of the more complicated patterns out there.

Happy Coding!

Saturday, February 20, 2016

Tracking Properties in Unit Tests - Update 3: Async Tests

When creating unit tests, we come across blocks of code that appear to be difficult to test. But with some thought, we can come up with some interesting solutions. Previously, we took a look at a test helper class that allows us to track changes to properties.

In recent articles, we've improved our PropertyChangeTracker class so that it works when "all properties" are updated and also added a finer-grained timout. This time, we'll create some asynchronous tests since that's the primary use case for the tracker class.

Articles in this Series
o Tracking Property Changes in Unit Tests
o Update 1: Supporting "All Properties"
o Update 2: Finer-Grained Timeout
o Update 3: Async Tests (this article)

Note: The completed code for this article can be found in the "TestConsolidation" branch of the GitHub project: jeremybytes/property-change-tracker.

Consolidating Tests
To simplify our tests, we'll reduce the number of fake classes that we have. When we originally set up the tests, we created separate fake classes for the different ways that we can implement INotifyPropertyChanged.

The result is that we had 3 sets of tests with 4 tests each (i.e. 12 tests total):


As we've seen in a previous article, all 3 of these fake classes actually get compiled down to the same code. Because of this, we really only need to have 1 fake class.

In addition, we should take a look at what we really need to be testing. Our tracker class is a test helper that ties into the "PropertyChanged" event on any class that implements "INotifyPropertyChanged". We aren't testing whether the PropertyChanged event is fired at the right time; we're testing that our tracker class behaves appropriately when the event *is* fired.

This means that we really only need one fake class (and consequently, one set of tests).

One Fake Class
So we'll get rid of the "FakeClassStandardProperty" and "FakeClassCallerMemberName". We'll hang onto the fake class that uses the "nameof()" expression, but we'll rename it to "FakePropertiesClass".

This gives us a single fake class. Here's a sample property:


The contents of the class are unchanged; only the name is different.

One Set of Tests
We can also delete our other test classes so that we only have one set of tests. Because we only have one set of tests, we can simplify the test names a bit as well.

Here are the first 2 tests for updates to a single property:


In addition, we have tests that check the functionality of the timeout and whether our tracker works when "all properties" are updated:


This means that we only have 4 tests (instead of 12):



Asynchronous Tests
The purpose of the PropertyChangeTracker class is to help us test classes that are updated asynchronously (see the original article for more information). Because of this, we should have some tests that update our properties asynchronously.

Let's add those tests.

Asynchronous Helper Method
To start with, we'll create a method that will do a property update asynchronously. This is a helper method inside our test class:


For the parameters, we pass in a delay (in milliseconds) and the fake class that we're using for testing.

The delay is used in a call to "Task.Delay()". "Task.Delay()" behaves similarly to "Thread.Sleep()" in that it pauses execution of our code. The difference is that "Task.Delay()" does not block the current thread.

We "await" the "Task.Delay()" call. This means that our code that sets the "LastName" property will not run until after the delay has completed.

One other thing to notice is the "ConfigureAwait(false)". Normally when we "await" an asynchronous method, it grabs the current context and the subsequent code runs in that same context -- this generally means it runs on the same thread.

When we use "ConfigureAwait(false)", the current context is *not* captured. So the subsequent code runs wherever the Task Scheduler sees fit. This often means that the code will run on a different thread.

Tests with Asynchronous Updates
So let's create a test that uses this code to update a property asynchronously.


In this test, we call "UpdateProperty" with a delay of 50 milliseconds. Then we ask our tracker class to "WaitForChange" with a max wait of 100 milliseconds.

Since our delay is less than our max wait, we would expect that the "LastName" property will be updated and our "WaitForChange" method will return "true".

And that's exactly what happens.

So let's try this again with a different max wait time:


This test still uses a 50 millisecond delay (for the "UpdateProperty" method), but is only uses a 20 millisecond max wait (for the "WaitForChange" method).

This means that our tracker class should stop waiting *before* the asynchronous update happens. And we see this in our test results:


The problem is that "WaitForChange" returns "false", but our "Assert" is still looking for "true". In fact, we should expect a "false" value here.

Here's our corrected test:


And now all of our tests give us the expected results:


Timing
Let's take a quick look at the run times for our asynchronous tests.

The 3rd test in our list, "Tracker_SinglePropertyAsyncCompleted_ReturnsTrue", takes 65 milliseconds to run. This includes the 50 millisecond delay that we have (plus the time it takes to run the rest of the test).

The 4th test in our list, "Tracker_SinglePropertyAsyncNotCompleted_ReturnsFalse", takes 19 milliseconds to complete. This represents the 20 millisecond timeout for the "WaitForChange" method. The timeout isn't exact due to the "while" loop and time calculation that is used in the "WaitForChange" method implementation.

But we can see that these timings are close to what we would expect.

Wrap Up
We've simplified our test suite quite a bit. We've removed redundancy from our tests and focused on what we really need to be testing for.

In addition, we added test code that updates a property asynchronously. This matches the actual use case for our PropertyChangeTracker class. I prefer tests that match real-world usage as much as possible. This gives us the best chance of finding potential bugs.

We'll keep the original (non-async) tests because it's still good to have a "sanity check" for our code.

It's good to review our code and tests. We often find that we have tests that we don't actually need and that we need additional tests that we don't currently have.

Happy Coding!

Friday, February 19, 2016

Tracking Properties in Unit Tests - Update 2: Finer-Grained Timeout

When creating unit tests, we come across blocks of code that appear to be difficult to test. But with some thought, we can come up with some interesting solutions. Previously, we took a look at a test helper class that allows us to track changes to properties.

In the last article, we improved our PropertyChangeTracker class so that it works when "all properties" are updated. This time, we'll look at adding a finer-grained timeout.

Articles in this Series
o Tracking Property Changes in Unit Tests
o Update 1: Supporting "All Properties"
o Update 2: Finer-Grained Timeout (this article)
o Update 3: Async Tests

Note: The completed code for this article is in the "Timeout" branch of the GitHub project: jeremybytes/property-change-tracker. (It has also been merged into the master branch with some other updates.)

The Problem: 1 Second Resolution
The shortcoming of our current property change tracker is with the maximum wait time in our "WaitForChange" method:


The parameter is an integer, and it represents seconds. This means that our minimum wait time is 1 second.

This is an *extremely* long time to wait in a unit test. We want our tests to run fast. The faster our tests run, the more frequently we will run them.

Right now we have 3 tests that look at the timeout. This means that we have a minimum of a 3 second runtime for our tests:


In fact, our total run time is 5 seconds:


This doesn't seem like a long run time. But we only have 9 tests here. Once our test suite has several hundred tests, we may be hitting the timeout a dozen times in those tests, and that significantly impacts the running time of our test suite.

Finer-Grained Timeout
Ideally, we want to have much more control over this timeout period. As a start, we'll update the "WaitForChange" method so that it uses milliseconds instead of seconds. This is pretty easy:


The calculations are pretty much the same (although I did refactor it a bit). The result is that our maximum wait (a.k.a. timeout) is now in milliseconds.

DateTime.Now vs. DateTime.UtcNow
Just a quick note: another change to this code is that we use "DateTime.UtcNow" instead of "DateTime.Now". This is a minor optimization.

In the framework code, it turns out that "DateTime.Now" makes a call to "DateTime.UtcNow" and then it adjusts for the local timezone. We can avoid that calculation by just using the UTC time. For practical purposes, this makes no difference in functionality*. But there is a very slight performance difference.

*Exception: We will run into an issue with "DateTime.Now" if we run the unit tests precisely during a Daylight Saving Time switch over.

Breaking Change
We just made a breaking change to our code. Previous calls to "WaitForChange" that used "1" as a parameter will now have a timeout of 1 millisecond instead of 1 second.

Here's one of our tests:


We can see the difference in our results:


Our tests still pass, but our timings are different. This would be an issue if we were testing asynchronous calls (which we'll add in a future article).

Test Fix
Fixing the test is easy, we just need to change the parameter:


Now we have a timeout of 100 milliseconds. When we update all of our tests, we see the results:


Our total run time is now 3 seconds:


And most of that 3 seconds is actually the test runner starting up. So we've accomplished our goal of having a finer-grained timeout for our tracker class.

But lets add one more option before we leave this code.

Overload with TimeSpan
In addition to the millisecond option, we'll add an overload to our "WaitForChange" method that accepts a TimeSpan as a parameter.

Here's our additional method:


The logic is pretty close to our other method, but now we aren't limited to millisecond resolution. We can create whatever timeout we would like.

Additional Unit Tests
To test this new method, we'll create some additional tests. Here is a new test that is in the "Standard Properties" tests (see previous article for details on the test suite):


In this test, we're looking at what happens when our "max wait" has expired (hence, the name of the test). In the set up, we create a TimeSpan that represents 60 milliseconds.

This test was added to the "CallerMemberName" and "nameof()" test classes as well.

Here are the results:


We can see the new results that have run times of "59 ms" each. Our total run time stays the same:


So now we have 2 ways of calling our "WaitForChange" method: with milliseconds or with a TimeSpan.

Coming Up: Additional Tests
We still need some additional tests. As mentioned previously, the primary purpose of our PropertyChangeTracker class is to help us test where we have asynchronous methods updating our properties. So far, all of our tests are synchronous code.

So we'll add some asynchronous tests to make sure that all of this code still works reliably. And with that, we can do some additional validation of the timeouts that we have in place.

Wrap Up
We want our unit tests to run fast. The code that we had limited how fast some of our tests could run. 1-second resolution was just too long to be practical. We could easily update this code to give us millisecond resolution; however, this was a breaking change so we need to update the calling code (in this case, in our tests).

In addition, we added an option to accept an arbitrary TimeSpan. This offers even more flexibility when we use the PropertyChangeTracker in our tests.

Our class is slowly becoming useful in a larger variety of situations. More to come.

Happy Coding!

Tracking Properties in Unit Tests - Update 1: Supporting "All Properties"

When creating unit tests, we come across blocks of code that appear to be difficult to test. But with some thought, we can come up with some interesting solutions. Previously, we took a look at a test helper class that allows us to track changes to properties.

I've found that this code is especially helpful when testing view models that use asynchronous method calls. For more information on this scenario, please see the prior article: Tracking Property Changes in Unit Tests.

Articles in this Series
o Tracking Property Changes in Unit Tests
o Update 1: Supporting "All Properties" (this article)
o Update 2: Finer-Grained Timeout
o Update 3: Async Tests

There were some shortcomings in the original implementation. The code worked just fine in the environment that I created it for, but it falls down once we start trying to use it as a more general tool. Now it's time to address those shortcomings.

To make sure that the changes would work in various scenarios, I created a stand-alone project and a set of unit tests. The code is available on GitHub: jeremybytes/property-change-tracker.

Here are the shortfalls of the original code (as described in the prior article):
  • Missed "All" Property Changed
  • The "while" Loop
  • Finer-Grained Timeout
  • Implementing IDisposable
Today we'll look at the first item: accommodating "all properties". And we'll also look at the initial tests that go along with this.

Note: The completed code for this article is in the "All Properties" branch of the GitHub project. (It has also been merged into the master branch with some other updates.)

Single Property vs. "All" Properties
When we implement the "INotifyPropertyChanged" interface, our goal is to get the "PropertyChanged" event to fire whenever we update one of our properties. This lets the UI know that the property has been updated, so the data-bound controls will re-bind their values.

For more information on this, check out the previous article that shows different ways to implement this code: CallerMemberName vs. nameof() in INotifyPropertyChanged.

In these examples, we have been passing in a specific property name, but we can also signal that *all* properties have been changed. Here's the documentation for the PropertyChanged event:



So we can pass "null" or "String.Empty" to fire the PropertyChanged event for all properties.

The Problem
The problem is that our PropertyChangeTracker code does not currently support "all properties". Here's the original code:


We have a "notifications" list that holds the names of the properties that have been changed. Then in our "WaitForChange" method, we look for the name of a property. But if "all properties" have been changed, then the string for the specific property will not appear in this list.

Test Classes & Unit Tests
Before making these changes, we'll set up some test classes and tests. Since there are multiple ways of implementing "INotifyPropertyChanged" (as we've seen), I decided to create 3 different test classes. This is technically not necessary because we've seen that the code gets compiled down to the same IL. But I initially approached this from a naive standpoint, so I wanted to "cover the bases".

Standard Properties Class
Inside the "TestHelpers.Tests" project is a "FakeClassStandardProperties" class. This uses quoted strings in the calls to RaisePropertyChanged. Here's a snippet with a sample property:


Then there is also a public method to update "all properties":


The "RaisePropertyChanged" method has a default value for the parameter. If no value is passed in, then "null" is used -- indicating that "all properties" have been changed.

Standard Properties Tests
To test our PropertyChangeTracker, we set up 3 initial tests. First, we look at a single property:


In the first test, we initialize our fake class and then hook up the PropertyChangeTracker. Then we change the "LastName" property and ask our tracker to wait for the "LastName" property to be changed. Since we just changed the property, the tracker will have it in its list of changed items, so it will return "true" immediately.

This scenario is a bit different than described in the original article on the change tracker because we are dealing with synchronous code. We will want to add tests in the future to test with asynchronous code since that's the primary reason for using this test helper. But for now, we'll stick with basic functionality.

In the second test, we initialize our fake class and hook up the tracker, but we do *not* change the property. This means that our "WaitForChange" method will wait for 1 second and then return "false" (meaning the property was not changed within the expected timeframe).

Note: One of our shortfalls of this object is that we have a timeout measured in seconds. This will be addressed in a future update.

Testing "All Properties"
In addition to these 2 tests, we have a third to test "all properties":


This has the same setup, but instead of updating a single property, we call the "NotifyAllProperties" method on our test class.

With our code in its initial state, this test will fail.

Testing with the CallerMemberName Attribute
We have another test class that implements INotifyPropertyChanged using the CallerMemberName attribute. This class is called "FakeClassCallerMemberName". Here's a sample property:


We don't have a quoted string when we call "RaisePropertyChanged" beause we are relying on the compiler to pass "FirstName" into the method. More information on the "CallerMemberName" attribute is available in a prior article: "Using the CallerMemberName Attribute for Better XAML Data Binding".

The method to update "all properties" is a little different:


Since we are using the "CallerMemberName" attribute, we don't want to leave the parameter empty. This would pass in "NotifyAllProperties" as the parameter, which is definitely not what we want.

Instead, we pass in an explicit "null". The "null" will then be passed through to the PropertyChanged event.

Unit Tests with the CallerMemberName fake class
The tests that go along with this fake class are pretty much the same as what we saw with the standard property fake class. So, we won't look at them here. Again, the test that uses the "NotifyAllProperties" method fails.

Testing with the "nameof()" Expression
As you might imagine, there is a third test class that implements INotifyPropertyChanged using the "nameof()" expression. Here's a sample property:


And a method to update "all properties":


Notice that this is the same as the class with standard properties. That's because we "RaisePropertyChanged" has a default value for the parameter, and since we do *not* have the CallerMemberName attribute, we can go back to relying on the default to pass in the "null" value.

Unit Tests with "nameof()"
Again, the unit tests that use this class are pretty much the same as the other tests, so we won't go through them here. As above, the test that uses "NotifyAllProperties" currently fails.

Adding Support for "All Properties"
So we have our tests in place. With our original code, we do get some failures:


This shows us that the tests which call the single properties pass, but the tests which update "all properties" fail.

The reason that the failing tests take 1 second to complete is because they wait for the timeout before returning "false". (Again, we'll address this timeout in a future article.)

Updated Code
I took the simplest path in order to add support for "all properties". I made changes to the PropertyChangeTracker in 2 locations. The first was the constructor:


If we compare this to the original constructor above, we see that there we added a conditional to check to see if the parameter is null or empty. This will handle both a "null" parameter or a "String.Empty" parameter, so this matches the specifications of the PropertyChanged event that we saw above.

As a simple path, I added a magic string to our notifications list: "***ALL***". I'm not a big fan of magic strings, but this code is pretty compact and isolated.

So let's look at the other part of the code: "WaitForChange":


In this code, we have added to the condition of the "while" loop. Instead of just checking for the property name, we also check for "***ALL***".

With this code in place, all of our tests now pass:


Considerations
I mentioned that I'm not a fan of magic strings, so why did I use one? Wouldn't it be better to check for the "all" parameter directly in the notifications list?

The answer is maybe. That's the code that I started with. The constructor would be unchanged from the original, but the "while" conditional looks like this:


With this code in place, all of the tests pass. But I wasn't happy with the readability. This is really a matter of opinion, so I won't recommend one over the other. But I have a preference for the version with the magic string because it's more readable. The class itself is small (only 45 lines of code), and the magic string is isolated (meaning, it doesn't cross class boundaries). So I'm willing to compromise in one area (magic string) to make another area better (readability).

Again, the code for this update is available in the "All Properties" branch on GitHub: jeremybytes/property-change-tracker.

Wrap Up
There was a bit of setup to get our tests in place. But once that was done, it was pretty easy to add our first improvement to the "PropertyChangeTracker" class. Next time around, we'll look at fixing our timeout so that we can have finer-grained values. One second is a really long minimum value, particularly if we have multiple tests that hit that timeout.

Also in the future, we'll look at adding tests that explicitly test our tracker with asynchronous code. This is closer to the real-world use for this test helper. And we may look at potential threading issues as well.

When we're looking to add features to our code, it's important to have tests in place to make sure that we don't break any existing functionality. This let's us move forward confidently and gives us immediate feedback when something goes wrong. And that makes me a faster coder.

Happy Coding!

Sunday, February 14, 2016

CallerMemberName vs. nameof() in INotifyPropertyChanged

Last month, we took a look at some of the framework and language changes that make it easier to implement INotifyPropertyChanged in our classes. Two of those changed included the "CallerMemberName" attribute and the "nameof()" expression.

Antoine left a great question since the functionality of "CallerMemberName" and "nameof()" seem so similar:
I don't see the point of using nameof() instead of the CallerMemberName though, is it about performance?
Let's take a closer look, first to see if there are any performance differences, and then see an example of why I prefer to use "nameof()": calculated properties.

Review: Using a String Parameter Directly
Let's look at why we want to use either "CallerMemberName" or "nameof()". For this, we'll do a quick review of how we implemented INotifyPropertyChanged before we had these.


This is a typical implementation of INotifyPropertyChanged (although you'll probably notice that we're using the null-conditional operator that we learned about before).

We could then call "RaisePropertyChanged" in our property setter by passing in the name of the property as a string:


This works, but wherever we have quoted strings, we have good places for things to break. For example, if we type the name of the property incorrectly, it will not work. If we change the name of our property, it's likely that our refactoring tool will not change the string, and it will not work.

So we'd like an option where we don't have to use a quoted string for the property name.

Review: Using "CallerMemberName" Attribute
One option is to use the "CallerMemberName" attribute (which was added to the framework in .NET 4.5), we put the attribute into our implementation of INotifyPropertyChanged:


Because the "CallerMemberName" attribute is placed before the first parameter of our "RaisePropertyChanged" method, the name of the calling item will be substituted here. So that means our property setter can look like this:


Notice that we do not pass a parameter to "RaisePropertyChanged". But because we have the attribute on the parameter, the string "FirstName" (the name of our property) is passed in automatically.

This fixes our initial problem because we no longer have a quoted string to worry about.

For more information on the "CallerMemberName" attribute, see "Using the CallerMemberName Attribute for Better XAML Data Binding".

Review: Using the "nameof()" Expression
A new option that we got with C# 6 (and the Visual Studio 2015 compiler) is the "nameof()" expression. To use this, we don't need to do anything special with our implementation of "INotifyPropertyChanged":


Notice that this implementation is exactly the same as our first example where we use the string parameter directly.

But instead of using a string parameter, we use the "nameof()" expression in the property setter:


When we use "nameof(FirstName)" in our code, it will pass the string "FirstName" as a parameter to "RaisePropertyChanged", so we get the correct value. And this has the added benefit of not being a quoted string.

This means that if we type "FirstName" incorrectly, we will get a compiler error. In addition, if we rename the property, our refactoring tools will automatically update the "nameof()" expression as well.

So why do I prefer "nameof()" to "CallerMemberName"?

Are There Performance Differences?
The first thing to do is look at performance. It turns out that all three of these implementations generate the same compiled code.

To take a look at the sample code, go to the "property-change-tracker" project on GitHub: jeremybytes/property-change-tracker. Inside of the "TestHelpers.Tests" project, there are classes that have all three implementations:


FakeClassStandardProperties
The "FakeClassStandardProperties" uses the quoted string parameters. If we look at the IL (intermediate language) that the compiler generates for the "FirstName" property, we see this code:


(Just a snippet). Notice the string "FirstName". This quoted string is used as the parameter for the next line, which is a call to "RaisePropertyChanged".

That's not much of a surprise, but let's look at the other classes.

FakeClassCallerMemberName
The "FakeClassCallerMemberName" uses the "CallerMemberName" attribute like we saw above. Let's look at the IL that is generated by the compiler:


This also has the quoted string "FirstName" which then gets used as a parameter for "RaisePropertyChanged". The compiler generates the same code as if we pass in the string directly.

So this means that there is no performance difference (at least at runtime), when we use the "CallerMemberName" attribute in this sceneario.

FakeClassNameOf
The "FakeClassNameOf" uses the "nameof()" expression like we saw above. Here's the IL that's generated:


Again we see the "FirstName" quoted string in our IL.

So this means that there is no performance difference if we use the "nameof()" expression in this scenario.

With no performance differences, why do I prefer "nameof()" over "CallerMemberName"? Let's take a look at another scenario: calculated properties.

Consistency and Calculated Properties
I've written a lot of user-facing applications. And quite often, these applications would have calculated properties -- properties that were based on 1 or more other properties. Here's an example:


If we have an order form that has both "Quantity" and "Price" properties, then we may also want a "TotalPrice" property that is calculated from these values.

In this case, if the "Quantity" is updated, then I want the "TotalPrice" property to be recalculated. In our data binding world, this means that we also need to call "RaisePropertyChanged" for our "TotalPrice" property.

Using the CallerMemberName Attribute
If we use the "CallerMemberName" attribute in this scenario, then our "Quantity" property may look like this:


The first "RaisePropertyChanged" (without a parameter), will get "Quantity" passed in. But for the second call to "RaisePropertyChanged", we need to explicitly pass a parameter so that we can also raise the PropertyChanged event for "TotalPrice".

Now, we know that using a hard-coded string here is not a good idea. That's the whole reason we want to use one of these other features. So, it makes more sense to update the code like this:


So the first call to "RaisePropertyChanged" (without the parameters) still raises the PropertyChanged event for "Quantity", but then the second call will raise it for "TotalPrice". And again, we get the benefits of not using a hard-coded string here.

Consistency with the nameof() Expression
And this is where I want to take things one step further. If I only have *one* call to "RaisePropertyChanged", then I don't have to do much thinking -- of course, this will reference the current property.

But when I have *two* calls to "RaisePropertyChanged", and one of them doesn't have any parameters, I need to start thinking a little more. Instead of this, I'd rather just use the "nameof()" expression for both calls.


This gives my brain something that is really easy to process. Without having to think about details, I know that this raises the PropertyChanged event for both "Quantity" and "TotalPrice".

Wrap Up
The "CallerMemberName" attribute and the "nameof()" expression both give us the same key benefits: (1) they eliminate the quoted string in our properties, and (2) they don't affect runtime performance.

But once we start to look at other scenarios -- like having calculated properties -- we see that "nameof()" can give us consistency in our properties that makes them easier to read and understand. And when we're dealing with code, human readability is a key feature.

In the applications I've spent most of my career with, calculated properties are pretty common. Because of that, I prefer the "nameof()" expression. But if you have classes that have no calculated properties (which is common when using entity classes), you may get better readability by using the "CallerMemberName" attribute.

A big part of making these types of decisions is to understand our environment. This helps us make the right decision for our particular application.

Happy Coding!