Sunday, December 21, 2014

Git Integration in Visual Studio 2013

I'm still fairly new to Git. Last week I talked about how I got comfortable with Git (Git While the Gittin' is Good). Since then, I've pretty much decided to start using Git for all of my new projects. And that's when I discovered something really cool: Visual Studio integration for Git.

Now, I haven't been living in a hole. I remember a while back when it was announced that Visual Studio started to support Git for source control (in addition to Team Foundation Server source control). I also remember hearing about a lot of folks who jumped on it right away and found that it was a bit difficult to get started.

But it's not that way anymore. So, let's create a new Git repository and see what we get in Visual Studio.

[Note: Git articles are collected here: Learning Git. And a video is also available: Git Basics for Visual Studio Developers.]

Creating a New Repository
A couple weeks ago, I published a video series on C# Delegates. Someone left a comment asking me to show using delegates with unit tests. So, I sat down to do some quick tests to see what I could come up with for those samples.

I started with the "starter" code that I showed in the video (just the base project). Here are the files (along with a ".gitignore" file that I already copied into the folder):


So, let's set up a repository for this project. First, we create a repository with "git init":


And that creates the ".git" folder on the file system:


This is a hidden folder, so depending on your settings, you may not be able to see ".git". I always show hidden files and folders (and also file extensions).

So far, so good. Next, we can run "git status" to see how things look:


This tells us that we have some files that are not being tracked by the repository. Notice that the user file "FuncActionDelegates.v12.suo" is not included in this list. That's because ".suo" is part of the items that we have in our ".gitignore" file. This is one of the reasons that it's important to have a good ".gitignore" (and we saw last week that GitHub has some for us already).

So, to start tracking these files, we should run the "git add" command:


The "." parameter says that we want to add all of the files and folders. If we run another "status", we see the files are now tracked, but they still need to be committed:


Then we commit the files:


For the "git commit" command, we used two different switches: "a" and "m". The "-a" says that we want to commit all of the pending files. The "-m" says that we want to include a commit message, which is what "Initial Project" is. We can combine the two switches into a single "-am" for our commit command.

And if we check the status...


We see that everything is all set. All of our files are now committed to our new repository.

Unexpected Things in Visual Studio
After setting up the repository, I opened the solution in Visual Studio. That's where I found out (completely by accident) that Visual Studio has a lot of Git integration. Here's what my solution looked like:


I noticed the lock icons next to my files. I'm used to seeing that when projects are hooked up to TFS source control. But I didn't do anything special for this to work with Git. Visual Studio just found the ".git" folder and started using it. I'm using Visual Studio 2013 Ultimate with Update 4. I'm not sure when the Git support was rolled in. I haven't installed anything special for this, so I guess it came in one of the updates.

[Update: Git integration has always been in VS2013. Apparently, I'm thinking back to VS2012 for the manual bits. More info on MSDN: Use Visual Studio with Git.]

So let's see what happens when we start to modify files. I made changes to the "Person.cs" file to add a custom delegate (like is shown in the video), and I also created a new unit test project. The source control information updated in the Solution Explorer with each change.

Here's what the changes look like:


And just to show that this matches what Git has, we can run another status:


This shows the same thing as the Visual Studio window. Our solution file has changed and also the "Person.cs" file. In addition, we have some untracked files -- everything in the "FuncActionDelegates.Tests" folder.

Back in Visual Studio, we can take a look at the Team Explorer window (since this is where we normally deal with source control stuff):


If we click on the "Changes" option, we can see what needs to be committed:


This shows us the same thing. We need to update the solution file and the "Person.cs" file. And we need to add a bunch of files in our "Tests" folder. Notice at the top, there's a place where we can put in our commit message.

Let's do that:


When we click the "Commit" button, everything gets committed.


This shows the commit, and also gives us a link to "Sync" to a server (such as GitHub). I haven't hooked this project up to GitHub, so we won't worry about this today.

If we go back to the command line, we can use "git log" to see our history:


This shows our commit from Visual Studio with our message "Initial Delegate and Tests".

Viewing History
In the Solution Explorer, we can also right-click on files and select "View History..." If we do this on the "Person.cs" file, we see the initial state and our change.


Even better, we can highlight both of these files, right-click, and select "Compare".


This shows the differences between the 2 files.

And if we have a changed file (like we have here)...


Our right-click menu has a number of options related to source control:


We can "Undo" to revert to the last committed version and "View History" as we saw above. I really like the "Compare with Unmodified" option. This gives us a side-by-side comparison with the current file and the last committed version. And finally, we can "Commit" from here. This will take us to the Commit window that we saw earlier to give us a chance to put in a commit message.

Other Options
There are lots of other options as well (which I haven't had time to play with yet), including branching and merging, configuring Git, and syncing to a server. Here's the window that lets us set up that remote repository:


And we can see that there are "Pull" and "Push" options available once we're hooked up.

So, lots of things to explore without needing to use the command line.

Wrap Up
Honestly, I wasn't expecting this to be so well integrated. I guess I had the things I had heard about the initial growing pains stuck in my head. It was a happy surprise to see that Git is so well integrated into Visual Studio without having to do anything special.

Now I am glad that I learned the basics of the command line. By doing that, I became familiar with how Git works as a distributed source control system (as opposed to the centralized source control systems that I've primarily worked with in the past). This gave me a good understanding of what was going to happen when I chose various options in Visual Studio.

Time will tell if I end up using the command line more or the Visual Studio tools more. With some practice in each one, I'll figure out what works best for my workflow.

In the meantime, if you've been worried about Git integration in Visual Studio, don't be. The basics are there (I don't know about the more advanced stuff since I'm still new to Git). So check it out. It's very easy to get started.

Happy Coding!

Thursday, December 18, 2014

Becoming a Social Developer: A Guide for Introverts

I'm not an extrovert. I know that's hard to believe for anyone who's met me at a developer event. When I'm presenting, I appear to be anything but introverted (and that's probably because I love to watch people learn, so I forget about it). And in the hallway or lunch line, I'm not afraid to strike up a conversation with a stranger. But this is all a relatively recent phenomenon for me.

By nature, I'm usually a listener more than a talker; I don't usually talk to people I don't know; and I usually have meals by myself with a book.

But I broke out of that for at least one part of my life -- involvement in the developer community. It was unnerving when I started, but it got easier, and it has turned out to be incredibly rewarding.

[Update 09/2015: For more on the topic, I've put down my experiences at That Conference in a recent article. And also be sure to listen to the .NET Rocks! podcast, episode 1187: Becoming a Social Developer with Jeremy Clark. And be sure to visit the official website: Becoming a Social Developer]

[Update 06/2016: I had a chance to share this at NDC Oslo. The video is available here: NDC Oslo - Becoming a Social Developer.]

Introvert or Extrovert
First, a quick look at what we mean by being an introvert or an extrovert. This doesn't really have to do with whether someone is "shy" or "outgoing"; it has to do with where a person derives their energy.

Introverts derive their energy from inside themselves -- often through introspection and quiet activities. This also means that crowds and frenetic environments can be exhausting. I know that in large, noisy gatherings, I often have to step out of a room for a few minutes to "reset".

Extroverts derive their energy from outside themselves -- often by being around other people and involved in large social gatherings. This also means that being by oneself can result in boredom.

So, this isn't about being "shy" or "outgoing"; it's about whether you derive your energy internally or externally.

The Loner at the Conference
I was very fortunate early in my career. I worked for a company that believed in training and conferences as a way to build up the team. So, I had the opportunity as a junior developer to attend professional conferences relevant to the type of work I was doing.

Unfortunately, I wasn't comfortable talking to people I didn't know. This meant that I didn't talk to anyone between the sessions, and mealtimes were stressful. The thing I hated most was walking into a banquet room and trying to pick a good table to sit at. I didn't want to "barge in" on groups of people who obviously knew each other and were having active conversations. So, I'd usually pick a table with just a couple people who may be sitting quietly. More often than not, I found out that the people I was sitting with were from overseas, and they were talking in Swedish. (Not that there's anything wrong with Swedish; I just don't understand it, so I couldn't participate.)

I enjoyed going to the conferences because I did learn a lot. But I didn't realize at the time just how much I was missing out on by not talking to other people.

Introverts Like to Talk
Over the years, I've formed the opinion that introverts like to talk, but they are reluctant to start a conversation. Here are a couple of examples that I've seen just in my involvement in the development community.

Now, I'm going to be using the words "introverts" and "developers" rather interchangeably. This isn't to say that there aren't extroverts in the developer community -- because there are. But there is a certain part of the developer stereotype that holds true: we're generally more satisfied spending time with our computers than spending time with other people.

So, if you're an extrovert, don't be offended. You can take this as a way to better understand the introvert developers that you interact with.

Code Camp Lunch
My "aha" moment came about 5 years ago. I was attending a code camp, and this was still early in my involvement in the developer community. At lunch, I was in the middle of the crowd to get tacos. After grabbing my food, I looked around and was a bit amused by what I saw.

The lunch was at a big grassy quad on a college campus, and there were individuals dotted around the lawn. In a rather stereotypic fashion, the developers had taken their food and found quiet spots to sit down and eat. That was my first inclination, too. But with this scene before me, I changed my mind.

I found someone (who didn't look too odd), introduced myself, and asked if I could sit down with him. We started with the standard "what do you do" and went on from there.

And then an interesting thing happened: someone came up an sat down with us. Then another person. And another person. As people got comfortable, they joined in the conversation. And by the time lunch was over, there were 2 circles of about 8 people each -- and I wasn't even facing the guy that I originally sat down with. These other circles had formed around us.

And this was all because I had started a conversation with one other person.

User Group
The first time I went to a user group, I got there a bit early. There were only 2 or 3 people there, and I didn't know anybody. My natural inclination was to fade into the background -- sit down and wait for someone to talk to me. But almost immediately, I said, "Nope, not gonna do that."

I went up to someone and introduced myself. And we started talking. As more people came in, they joined in the conversation (as opposed to going and sitting alone). After a while, there were 6 of us having a good conversation.

The Realization
After seeing this happen a few times, I had the following realization:
Developers like to talk, but they don't like to start the conversation.
Here's the standard progression.
  1. A developer sees a conversation in progress and goes up to listen.
    This is a "safe" activity. You can be seen as being social without exposing yourself.
  2. After getting the feel for the conversation, the developer makes a comment.
    This is a way to "test the waters" and find out how people will respond to you.
  3. After getting comfortable, the developer opens up.
    Now you are an active part of the conversation. You may feel free to open up different topics.
This doesn't mean that things are easy for an introvert. But we can take an active role in getting this progression started.

Becoming a Social Developer
It doesn't take much to become a social developer. The steps are very simple to follow -- and they are extremely hard to do the first time.

Step 1: Introduce yourself to someone you don't know.
All you have to do is say, "Hi, I'm Jeremy" (but use your own name). And usually you don't even have to ask for the other person's name; they'll respond with their name.

Step 2: Ask a non-threatening question.
I usually start with "What do you do?" And you would not believe how many times people say, "I'm a programmer." Yep, I pretty much assumed that already.

Step 3: Ask a follow-up question.
Next is, "What kind of applications do you build -- web, desktop, mobile?"

I won't lie to you: this is going to be very difficult the first few times you do this. It's extremely uncomfortable as an introvert to put yourself out there. By starting the interaction, you open yourself up to rejection (not great if you don't have a huge amount of confidence).

But here's the good news: I've never had someone tell me to go away. There have been times when conversations have been a little awkward and fizzled out. But 9 times out of 10, I've gotten to know someone new.

It Gets Easy
The more you do this, the easier it gets. I've been doing this for about 5 years now (which really isn't that long in the grand scheme of things), and it's second-nature to me now.

Another Code Camp Lunch
About a year after I started doing this, I went to a code camp that was about 400 miles from where I live. It was a *huge* event, and I only knew a few people who were there. Because there were so many people, I knew that I probably wouldn't find anyone familiar during lunchtime.

So, after grabbing my pizza, I looked around at the folks who were already eating. I found 2 people who were sitting near each other (but not talking to each other). I introduced myself and asked if I could join them, and they said it would be fine.

I started the conversation and found out that one person was a developer manager, and the other person was a business analyst.

Here's the interesting part: as we were wrapping up lunch, a person who was sitting nearby pulled me aside. He said, "I like how you went up to people you didn't know and just started a conversation. That was really cool." That gave me a chance to share my experience with him -- how it's not part of my nature, but I've seen that it works well.

Encouraging Others to Join In
This is easy for me now. And rather than standing around in a registration area or hallway, I'm likely to start a conversation with someone nearby. And once you're comfortable with this, you can encourage other people to join in.

At a recent code camp, I was in a circle of about 3 or 4 people in the quad. Another person inched up to the circle -- the "listening" phase mentioned above. Rather than letting him just stand there and go slowly through the phases, I introduced myself and asked his name -- pulling him into the conversation. If we create a welcoming environment around us, then other developers will be more comfortable and willing to join the conversation.

I try to actively engage "lurkers" in the conversation, creating a safe environment for them to get involved. Once you're comfortable with yourself, do what you can to help others get comfortable.

The Results
I don't think I can really quantify the results of this. I know *a lot* of people in the developer community -- way more than I feel like I should know. I've had a lot of one-off conversations where I never saw the other person again. But I've also built some really good relationships.

Tracking Technologies
In addition, I get a very good feel for what's going on in the developer community. I usually ask people about what technologies they are working with, what they like about it, what doesn't work quite as advertised, and so forth. That's one of the reasons why I got into Git -- a lot of the developers that I've talked to are using it regularly and really like it.

As another example, I've been talking to quite a few folks about Angular.js. I'm not currently in the web programming world, but the technology is interesting based on what I've heard. And folks are talking about upcoming changes and how they affect current and future projects. I feel like I have  window into another part of the development world that I don't normally deal with.

Fearless
The great part is that I'm no longer afraid to talk to people I don't know. For example, last year I went to an event for Pluralsight authors. There were a lot of famous people there: people who were well known book authors, who spoke at professional conferences, who made the rounds on the developer podcasts. And I wasn't shy about going up and introducing myself. I won't talk about who because I don't want to sound like I'm name dropping. But it's nice to go up to someone, introduce yourself, and then let them know how they were influential in your programming career. And some of these interactions turned into longer conversations.

A Huge Network
The same is true at the Microsoft MVP Summit. And as I've attended these events, I've become friends with a lot of people (which I wrote about last month). And now when I'm listening to a podcast, I can say, "Hey, I've talked to that person." I'm amazed at how I'm having that experience more and more as I've built my network of contacts over the years.

At the same time, I know lots of people in my local development community. In fact, when I was looking for a job, I had about a dozen people give me leads on positions that were available in their company. These are people I've never worked with, but they felt that I could be a good fit for their team based on the conversations that we've had. (And I've always thought that being a good fit for a team is more important than knowing a particular technology -- a good developer can learn a new technology. But that's a discussion for another day.)

Very Compartmentalized
As a final note, I'll say that this "talking to strangers" attitude that I've picked up has remained limited to the developer community. If I'm at social events, I'm still unlikely to talk to people I don't know. And if you're sitting next to me on an airplane, I'm unlikely to start a conversation (unless I know you, of course). There is a certain level of comfort in the developer community because we all know that we have at least one thing in common: programming.

Wrap Up
It's not easy to get started. But if you are an introvert developer, I'd recommend taking a chance. The next time you're at a user group or other developer event, introduce yourself to someone you don't know. The first time will be hard. But trust me, it gets easier.

And the results are well worth it.

Happy Coding!

Wednesday, December 17, 2014

Git While the Gittin' is Good

Okay, so I'm a bit late to the party, but I'm finally getting started with Git. This is something that I've been meaning to do for a really long time, but I haven't set time aside for it. The few times I've taken a brief look at it, it seemed pretty different from the source control I'm used to, and I knew that I'd have to dedicate some time to get my brain to adjust.

Although I've only been using it for a short time, I'm much more comfortable with the concepts than I was before. I think I'll be using it regularly from now on. Here's what I did to get started.

[Note: Git articles are collected here: Learning Git. And a video is also available: Git Basics for Visual Studio Developers.]

Initial Learning
First step was to learn something about Git. My initial search led me to Code School - Try Git. This gives a step-by-step introduction to basic commands. I liked this because it started at the very beginning of how to create a Git repository.

Overall there are about a dozen commands that are shown. This is an interactive experience. Each step has 3 different windows.

The description / instructions:

The command line:

The file system:

What's nice about this is that the command window is "live". So you can type whatever commands you like. In the example above, the instructions are to type "git add octocat.txt" (and you can also click the text to automatically add it to the command window). But in the command window, I typed "git status". This shows the status of the repository (with the file that needs to be added) as well as a hint message that I didn't type what I needed to complete that step.

This gives a bit of freedom to check status and list branches if you want to get some more information rather than simply mimicking the commands.

There are 25 steps altogether, including basics like adding, modifying, removing, and committing files, creating branches, and associating a local repository with a GitHub repo.

Installation
After going through this, I needed to install Git on my machine so that I could start trying it out myself. In addition, I created an account on GitHub (finally).

To download, I just went to http://git-scm.com/downloads. There were a few choices to make during the installation process. I'm not quite sure if I made the right decisions (such as the defaults for line breaks). I'll figure out if I made the right choices as I get some more experience.

One of the options is to integrate it with Windows Explorer. With that in place, you get some new options in the right-click menu in file explorer. These are things like creating new repositories, opening Git command windows and even a Git GUI application. I've tried to stick with the command line -- at least until I'm comfortable with the commands.

Git will keep track of changes, branches, and history all on the local machine -- there's no need for a repository on a server. Now obviously, there are advantages and disadvantages to this. The biggest advantage is that you can commit changes, create branches, and revert to previous versions all while being off line.

I really like the idea of this because I don't live in the "always connected" world. I like to have applications that work even when I don't have a network connection. And Git definitely offers that.

GitHub
The downside to having everything on the local machine is that it's not automatically backed up on a server somewhere. And that's where something like GitHub comes in. GitHub hosts your repositories (among other things) so they are somewhere other than just on your local machine. Plus, it makes it really easy to sync repositories with other machines and share your code with the public.

To create an account, just go to http://github.com. In addition to walking you through the process of creating an account, it also has some pretty good guidance for creating repositories -- suggesting files to add, putting in ".gitignore" files, and so forth.

And having a prebuilt ".gitignore" file is really cool. The ".gitignore" file is how you tell Git about the items that you do *not* want to be tracked. For example, in the Visual Studio world, we don't usually want anything in the "bin" or "obj" folders in our repository. GitHub has a whole bunch of files supporting different languages and environments. You can take a look at the Visual Studio file here: https://github.com/github/gitignore/blob/master/VisualStudio.gitignore.

This is a fairly extensive file, and people keep adding to it. In addition to the basics, it also ignores test results, ReSharper files, and many other tools files. The nice thing about this is that it is a file in a GitHub repository, so the community is involved in keeping this up-to-date (57 contributors so far).

Git Practice
One of the reasons that I wanted to explore Git and GitHub was because I had seen presenters use it in their demos -- using branches to jump to different versions of the code to show progress. Recently, a few other folks I know have been looking into this. Joe Guadagno is one of those folks. He posted a demo that has branches for each of the steps: https://github.com/jguadagno/AzurePhotos.

It's interesting to look at the branches:

This way, you can jump to a specific step, and you can also use comparison tools to see what the differences are between files.

My Repository
So, I decided to try to put together something similar. I started with my simplest demo -- showing the syntax of a lambda expression. You can see the demo in action on YouTube: Anatomy of a Lambda Expression.

This gave me a chance to create a local Git repository, add the ".gitignore", and add the initial project files. Then I did step-by-step changes to the code and committed the changes after each step. Then I figured out that I really wanted to have branches (like Joe's repo) rather than just individual commits, so I deleted the ".git" folder and started all over again.

Yep, that's right, I deleted the repo and started all over. It was really easy to do. And I was walking through established demo steps, so I didn't have any history that I needed to hang on to.

This time, I created branches as I walked through the steps. This demo is pretty simple, but it's pretty important to show each step. I ended up with 7 branches in all -- many of them only having a difference of 1 line of code.

After I got things the way I wanted them, I pushed it to GitHub. You can see the repo here: https://github.com/jeremybytes/lambda-syntax.

Including all the branches:

What I Learned
I'm not sure if I'll be posting my demos like this to GitHub. But this exercise was very helpful for me. I have a much better handle on how to use Git. Here are the commands that I used in this process:
  • init
  • add
  • commit
  • status
  • log
  • branch
  • checkout
  • merge
  • push
  • remote
It wasn't a fast process, but it wasn't that difficult, either. There were times when I had to go back and look up commands or review the steps from the "Try Git" lessons. And I also had to Google some error messages. But after spending a couple hours with it, I'm pretty comfortable. I know that I still have a lot more to learn, but with the basics under my belt, I'm much more likely to use it regularly and move forward to learn the other features.

I have a system that works pretty well for me from a presentation perspective. So although I may not put everything I have on GitHub, I'll start putting my code into local Git repositories. And I can already think of a few projects that I can put online to share with other folks (like Conway's Game of Life, the rewrite of the legacy project, and the practice code analyzer).

I'm very glad I finally got around to this. Git is definitely a useful tool, and I see myself using it regularly moving forward. If you're not already using it, be sure to take a look at it to see how it can fit into your workflow.

Happy Coding!

Wednesday, December 10, 2014

New Video Series: C# Delegates

I've been talking about delegates for several years now. As with most of my topics, this is something that took a while for me to wrap my head around. But once I "got it", I saw how useful delegates are. They let us use methods as parameters to other methods -- this let's us incorporate functional-style programming into our C# code. In addition, since lambda expressions are simply anonymous delegates, they are much easier to understand once we have a good handle on what standard delegates are.

To help other folks "get" delegates, I just put together a video series on C# Delegates. Check it out on YouTube.

C# Delegates (Playlist)
Do you use delegates in .NET? If so, then Func and Action are just waiting to make your life easier. Not using delegates? Maybe you should. We'll take a look at what delegates are, why you would want to use them, and how to use Func and Action to tie things all together (with a few Lambdas thrown in just for fun).
  • Part 1: Basics
    In this video (first of a series), we'll look at the basics of delegates, including how to create a new delegate type, how to pass a delegate as a parameter to a method, and how to select what method we execute at runtime rather than compile-time. Along the way, we'll see how delegates can help us adhere to the S.O.L.I.D. principles.
  • Part 2: Getting Func<>-y (+ Lambdas)
    In this video, we'll see how we can use the built-in delegate type "Func" instead of using a custom delegate. In addition, we'll see how lambda expressions can make our code very compact and easy to read.
  • Part 3: Action<> and Multicast Delegates
    In this video, we'll use the built-in "Action" delegate. Along the way, we'll see how multicast delegates allow us to run multiple methods by invoking a single delegate variable.
For the sample code and supplemental articles, head over to my website: Get Func<>-y: Delegates in .NET

So in less than an hour, you can understand delegates a bit better. They are pretty awesome. And it's an important step to get a firm grasp one of my favorite topics: lambda expressions.

Happy Coding!

Monday, December 8, 2014

Updates to the "IfBracesAnalyzer" Code Fix Method

Last week, I published a video on creating a code analyzer with the .NET Compiler Platform "Roslyn" (Building a Diagnostic Analyzer with Code Fix in Visual Studio 2015). As I mentioned in the video and the accompanying article, I have not been working with Roslyn for very long, and I keep learning how to do things a little better.

So, I have a few updates to the code fix that we built. (And I'm still waiting to hear from my friends who have been working with Roslyn for a while; I'm sure they have some suggestions as well.)

The Original Method
Here's the method that we build in the video:


Here's a reminder of what this does:
  1. We take the "Statement" property of our "ifStatement" (which comes in as a parameter) and cast this to "ExpressionStatementSyntax".
    We can safely make this cast (and we don't need to check for nulls here) because we did that filtering in our diagnostic analyzer. So we already know that the "Statement" is an "ExpressionStatement" that needs to be wrapped in braces.
  2. Next. we create a new "Block" statement with the "SyntaxFactory". The parameter is the statement we want to wrap.
    In addition, we add "WithAdditionalAnnotations" so that the block will be formatted nicely in our code.
  3. Then we use the "ReplaceNode" method to swap out the old (non-braces) statement for the new block that we just created.
    As a reminder, nodes are immutable, so this returns us a new object.
  4. We get the "root" node from our document. This contains the entire syntax tree.
  5. Then we use the "ReplaceNode" method to swap out the old if statement for the updated if statement.
    Again, this creates a new root rather than modifying the existing one.
  6. After we have our new root, we call "document.WithSyntaxRoot" to create a new document.
    This new document will have all of the same properties as our old document, but we are replacing the contents with our updated root.
  7. Finally, we return the new document.
With this code fix in place, we can add curly braces to an if statement that needs them.



A Few Updates
There are a few minor updates that we can do to this code. The first has to do with our call to "ReplaceNode" on the "ifStatement". Here is the original:


We need to cast our parameters to "SyntaxNode" because the types are different: the first is "ExpressionStatementSyntax" and the second is "BlockSyntax". Now it's a bit subtle, but notice that "SyntaxNode" is greyed-out. Technically, we only need one cast -- it doesn't matter which one -- and the compiler will take care of the other one. But that may make things unclear when we're reading the code.

To clean things up a little, we can remove the cast and provide explicit generic types for the method. Here's what that looks like:


The first generic type is the type that we're working with ("IfStatementSyntax"), and the second generic type is the type for our 2 parameters ("SyntaxNode"). By specifying the generic type, we no longer need to cast the parameters; the compiler will handle everything for us. I think this is a bit easier to read.

The next fix has to do with how we retrieve the syntax root of our document. Here's the original:


This is an asynchronous method call. It turns out our entire method is also async, and it includes a cancellation token as a parameter. So we really should pass the cancellation token along to any async methods that we call.

Here's our updated call:


Eliminating Steps
The biggest change we'll make is to eliminate some steps. It turns out we're doing some extra work that we don't need. Let's look at our "ReplaceNode" method calls.
First, we use "ReplaceNode" to update the if statement -- this is where we swap out our old expression for the one wrapped in a block.
Later on, we use "ReplaceNode" to update the root -- this is where we swap out the old if statement for the updated if statement.
We can skip the intermediate step and simply replace the old expression for the new block in the root itself. Here's the updated method:


And here are the steps:
  1. We take the "Statement" property of our "ifStatement" (which comes in as a parameter) and cast this to "ExpressionStatementSyntax".
  2. Next. we create a new "Block" statement with the "SyntaxFactory". The parameter is the statement we want to wrap.
    Then we use the "ReplaceNode" method to swap out the old (non-braces) statement for the new block that we just created.
  3. We get the "root" node from our document. This contains the entire syntax tree.
    Note that we pass the cancellation token to this asynchronous method.
  4. Then we use the "ReplaceNode" method to swap out the old (non-block) statement for the new block statement.
    Since we specify "SyntaxNode" for the generic type, we do not need to cast the parameters.
  5. After we have our new root, we call "document.WithSyntaxRoot" to create a new document.
  6. Finally, we return the new document.
This is not a huge difference, but we do eliminate one of our steps. Optimization of the code fix is not as critical as optimizing the diagnostic analyzer, but it is always good to eliminate code that we do not need.

As a reminder, we want our diagnostic analyzer code to run as quickly as possible. This code is constantly running against our code in Visual Studio. If we aren't careful, this can really bog things down. The code fix only runs when we choose to show the fixes, so this requires some user interaction. But the code fix does need to run to show the preview, and it also may run multiple times if we choose "fix all occurrences", so we don't want it to be slow, either.

Wrap Up
A big part of being a developer is going back and taking another look at the code we've written. Often we'll find that we can optimize the code because we've learned more about the API. Sometimes, we question readability because it doesn't look quite as clear as when we wrote it.

This doesn't bother me at all. I see this as a sign that I am constantly improving. And I look forward to hearing what some other folks say about this code so that I can improve further.

Happy Coding!

Friday, December 5, 2014

Are You an Over-Abstractor or an Under-Abstractor?

I really like to teach people about different techniques of abstraction. If you don't believe me, just check my website: Interfaces, Dependency Injection, Design Patterns, and even the BackgroundWorker Component (and also my courses on Pluralsight).

One of the reasons that I talk about these particular topics is that they are things that took me a really long time to understand myself, so I like to help people take a short-cut to understanding. But that leads to a problem. Once we learn about them, we might want to use them everywhere, and we end up building a complex mess that's hard to maintain.

But over-abstraction is not our only problem. If we have too little abstraction, then our applications can be rigid and hard to maintain. So as developers, our goal is to find the sweet spot right in the middle. This is why I came up with "Abstract Art: Getting Things 'Just Right'" (which I give as a live presentation and as a course on Pluralsight). We're really looking to follow the Goldilocks Principle when it comes to abstraction: not too much, not too little, but "just right".

The Goldilocks Principle (from the presentation slides)

Observing Developers
So why do we, as developers, have a problem getting abstraction right? There are a number of factors, but the biggest one has to do with our natural tendencies. I'm not sure if anyone has done an official study on this, but I formed this opinion based on my observations of developers that I've worked with (and also by reflecting on myself).

The premise is that every developer has a default state as either an over-abstractor or an under-abstractor. Over-abstractors like to build stuff and think about all the possible uses of an application in the future. This may lead to overly complex implementations for features that will probably never get used. Under-abstractors like to keep things simple. This may lead to things like global variables, tightly-coupled components, and "god classes" with all sorts of functionality.

This is just our "default state" -- meaning, without any external influences, we lean one way or the other. But as we gain experience as developers, we run into difficulties with our default state and so we go in the other direction. This often results in us swinging too far, and we end up correcting back the other way.

The Pendulum Effect (from the Pluralsight course)

Eventually, we figure out the dangers of both over-abstraction and under-abstraction through trial-and-error. The main reason I wrote my presentation and Pluralsight course is to give people some best practices so they can skip some of these bad experiences.

One Group is Not Better Than the Other
The first time I gave this presentation, I ran into a bit of a problem: one of the attendees thought that I was promoting one group over the other -- for example saying that under-abstraction is better than over-abstraction. And that is definitely *not* the case.

Both groups have problems. With too much abstraction, we end up with code that is overly-complex, difficult to debug, and can cause frustration in people who are not intimately familiar with the code (which may include the original developer 6 months later). Ultimately, the code is difficult to maintain.

With too little abstraction, we end up with code that is rigid. It is hard to find bugs and very difficult to test. Ultimately, the code is difficult to maintain.

So we have a common result: code that is difficult to maintain. What we need to do is figure out how to recognize our natural tendency so that we can watch for the warning signs and hopefully end up with abstractions that are "just right" for our application.

Do You Meet More Over-Abstractors or Under-Abstractors?
In my presentations, I would love to do an informal survey to see if the developers identify themselves as over-abstractors or under-abstractors. But because I want to be careful not to create "teams" in the room, I don't do that.

I've been curious if there are more over-abstractors or under-abstractors in our field (or if there's an even split). I've been able to make the case of both groups.

The Case for Over-Abstractors
The main reason I would think that there are more over-abstractors in our field is that what we do is all about problem solving. We are developers because we like to come up with creative solutions and then implement those solutions by building things.

And a big part of that is the building. We don't want to use code that someone else wrote; we want to write it ourselves. This is often referred to as the "not invented here" syndrome.

Another part of this is that we like to plan for the future. Sure, we could build a robot that fetches a soda from the refrigerator. But wouldn't it be cooler if the robot would also vacuum as it goes? (Yeah, I know, we already have a vacuum cleaner that works well, but it will still be cool.) This is a fairly common mindset that we see in developers -- we are creative people.

Based on this, I might think that there are more over-abstractors in our industry.

The Case for Under-Abstractors
The main reason that I  would think there are more under-abstractors in our field is that there are a lot of developers who do not understand abstraction or what it is good for. As a young developer, I had a lot of trouble understanding why I would want to use interfaces in my code. I could tell they were important, but I couldn't find the right person to explain it to me. (This is one of the main reasons that I like to talk about Interfaces -- I don't want developers to go through the same struggle that I did.)

I come across a lot of developers who are like I was: they do not understand the basics of abstraction. I meet some of these developers when I'm helping them with their code; I meet some of these developers at my presentations. And my goal is to give them a better understanding of the topic while I have a chance to talk to them.

Based on this, I might think that there are more under-abstractors in our industry.

Any Ideas?
So, what are your thoughts? How do you identify yourself? Do you have more over-abstractors or under-abstractors where you work? What about the developers you meet at conferences or other events?

If you're not sure where you fall, you can check out the "Default State Quiz" that's part of my Pluralsight course.

By nature, I am an under-abstractor, but I've also swung into the over-abstraction world for a while. After my many years of experience, I like to think that I'm pretty well balanced, but I still have a tendency to lean toward my "default state" from time to time.

The first step to overcoming my default state was to recognize it. Since I've done that, I can now catch the times when I'm leaning too far toward under-abstraction. This gives me a chance to review some best practices to steer myself to a more balanced state.

Feel free to leave a comment with your thoughts (or drop me a note privately). I'm interested to hear what you think about the topic.

Happy Coding!

Wednesday, December 3, 2014

New Video: Building a Diagnostic Analyzer with Code Fix in Visual Studio 2015

Code analyzers are pretty cool. Many of us have been using ReSharper or another third-party tool with Visual Studio for many years. With the latest preview of Visual Studio 2015 and the .NET Compiler Platform ("Roslyn"), it's really easy to build these code analyzers for yourself.

You can spend about 45 minutes following along with me in my latest video:

Building a Diagnostic Analyzer with Code Fix in Visual Studio 2015
The .NET Compiler Platform ("Roslyn") allows us to easily create diagnostic analyzers that can alert us to issues in code as well as provide automated code fixes. We'll create a very simple analyzer and fix to show how easy this is to do. This uses the Visual Studio 2015 Preview, and instructions on getting what you need are in the video.
Here's a sample that I built:


This analyzer looks for "if" statements that don't have curly braces, warns us about it, and then offers to add the braces for us automatically.

You can get the code from my website: http://www.jeremybytes.com/Downloads.aspx#Analyzers

New to Roslyn
Now, I am very new to Roslyn (now called the ".NET Compiler Platform"). Many people I know have been working with it for years, but I've been struggling with whether it is relevant to me. I still don't have the answer to that question.

But at the MVP Summit last month, there was a hackathon where we built diagnostic analyzers and code fixes. This was a whirlwind introduction to Roslyn, the syntax visualizer, and the diagnostic analyzer project template. After going through the demo, I slowed down to try to understand things a bit better.

Today, I released a video that shows my initial exploration. I write a simple code analyzer and walk through the process of building it. You can watch the video on YouTube: Building a Diagnostic Analyzer with Code Fix in Visual Studio 2015.

I'm definitely not an expert (just a month in to actually using it). But I thought it would be useful to share my experiences.

If nothing else, this has given me a good appreciation for what benefits we get with the .NET Compiler Platform so I can think about possible uses in the future.

Happy Coding!