The opinions expressed in these materials are my own and are not necessarily those of Microsoft.
Copyright © Microsoft Corporation. All rights reserved. Unless otherwise indicated, all source code provided is licensed under the Microsoft Public License (Ms-PL).
Menu: Project -> Add New Solution Folder; [Right-Click Solution] -> Add -> New Solution Folder Command: Project.AddNewSolutionFolderVersions: 2008,2010Published: 3/27/2010 Code: vstipProj0009
Did you know there are special folders to help you organize large solutions? There is! They are called, appropriately enough, Solution Folders. To create one just Right-Click on your solution (or go to Project -> Add New Solution Folder) and you will see this in Solution Explorer:
Simply give the folder a name and you are good to go. But so what? I mean, what can you actually DO with these things? Here is a list of stuff you can do:
Move or add projects to them. Solution Folders can be nested to create greater organizational structure.
Add, delete, or rename Solution Folders at any time, if the organizational requirements of the solution change.
Unload all projects in a Solution Folder to make them temporarily unavailable for building.
Collapse or hide entire Solution Folders so that you can work more easily in Solution Explorer. Hidden projects are built when you build the solution.
Build or rebuild all the projects. The projects are built in the order specified by the project dependencies.
Solution Folders are an organizational tool in Solution Explorer; corresponding Windows folders are not created. Microsoft recommends that you organize your projects on disk in the same way that you organize them in the solution. But that is your call :)
SKU: Premium, Ultimate
Versions: 2008, 2010
As we continue looking at code metrics in Visual Studio (see vstipTool0129, “Calculating Metrics”), it’s time to look at class coupling. Class coupling also goes by the name Coupling Between Objects (CBO) as originally defined by [CK94]. Basically, class coupling is a measure of how many classes a single class uses. A high number is bad and a low number is generally good with this metric. Class coupling has been shown to be an accurate predictor of software failure and recent studies have shown that an upper-limit value of 9 is the most efficient [S2010].
According to the MSDN documentation, class coupling “[m]easures the coupling to unique classes through parameters, local variables, return types, method calls, generic or template instantiations, base classes, interface implementations, fields defined on external types, and attribute decoration. Good software design dictates that types and methods should have high cohesion and low coupling. High coupling indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types.”
The concepts of coupling and cohesion are clearly related. To keep this discussion on topic, I will not get into depth with cohesion other than to give a brief definition from [KKLS2000]:
“Module cohesion was introduced by Yourdon and Constantine as ‘how tightly bound or related the internal elements of a module are to one another’ [YC79]. A module has a strong cohesion if it represents exactly one task […], and all its elements contribute to this single task. They describe cohesion as an attribute of design, rather than code, and an attribute that can be used to predict reusability, maintainability, and changeability.”
Let’s look at class coupling in action. First, create a new console application and create a new class called Person with some properties in it then immediately calculate the code metrics:
Notice the class coupling is 0 since this class doesn’t use any other classes. Now create another class called PersonStuff with a method that creates an instance of Person and sets the property values. Calculate the code metrics again:
See how the class coupling value goes up? Also notice that, no matter how many properties we set, the class coupling value just goes up by 1 and not by some other value. Class coupling measures each class only once for this metric no matter how much it is used. In addition, can you see that DoSomething() has a 1 but the constructor, PersonStuff(), has a 0 for its value? Currently there is no code in the constructor that is using another class.
What if we put code in the constructor that used another class? Here is what you get:
Now the constructor clearly has code that uses another class and the class coupling metric shows this fact. Again, you can see the overall class coupling for PersonStuff() is 1 and DoSomething() is also 1 to show that only one external class is being used no matter how much internal code we have that uses it.
Next, let’s create another new class. I’ll call my class Blah and create some properties inside it:
Now consume the class in our DoSomething() method within the PersonStuff class and calculate code metrics again:
As you can see, the class coupling for the PersonStuff class goes up to 2 and, if we drill into the class, we can see that the DoSomething() method has the most coupling in it but the constructor still only consumes 1 class. Using these metrics we can see the overall max number for a given class and drill down into the details on a per-member basis.
As I mentioned with cyclomatic complexity (see vstipTool0131, “Code Metrics - Cyclomatic Complexity”), there is no limit that fits all organizations. However, [S2010] does indicate that a limit of 9 is optimal:
“Therefore, we consider the threshold values […] as the most effective. These threshold values [for a single member] are CBO = 9[…].” (emphasis added)
When using code analysis, the Extended Design Guideline rule set contains a maintainability area:
Inside the maintainability area is a rule for class coupling:
This rule issues a warning when the class coupling is excessive. You can learn more about the rule here:
Unfortunately, the documentation doesn’t talk about the thresholds set for this rule but I did find a description on the Code Analysis Team Blog (http://blogs.msdn.com/b/codeanalysis/archive/2007/11/15/code-metrics-as-check-in-policy.aspx): “Warning at above 80 for class and above 30 for a method”. These seem abnormally high but at least provide an extreme upper limit. If you hit this warning then something is almost certainly wrong.
Chidamber, S. R. & Kemerer, C. F. (1994). A Metrics Suite for Object Oriented Design (IEEE Transactions on Software Engineering, Vol. 20, No. 6). Retrieved May 14, 2011, from the University of Pittsburgh web site: http://www.pitt.edu/~ckemerer/CK%20research%20papers/MetricForOOD_ChidamberKemerer94.pdf
Kabaili, H., Keller, R., Lustman, F., and Saint-Denis, G. (2000). Class Cohesion Revisited: An Empirical Study on Industrial Systems (Proceedings of the Workshop on Quantitative Approaches in Object-Oriented Software Engineering). Retrieved May 20, 2011, from Université de Montréal web site http://www.iro.umontreal.ca/~sahraouh/qaoose/papers/Kabaili.pdf
Subramanyam, R. & Krishnan, M. S. (2003). Empirical Analysis of CK Metrics for Object-Oriented Design Complexity: Implications for Software Defects (IEEE Transactions on Software Engineering, Vol. 29, No. 4). Retrieved May 14, 2011, from University of Massachusetts Dartmouth web site http://moosehead.cis.umassd.edu/cis580/readings/OO_Design_Complexity_Metrics.pdf
Shatnawi, R. (2010). A Quantitative Investigation of the Acceptable Risk Levels of Object-Oriented Metrics in Open-Source Systems (IEEE Transactions on Software Engineering, Vol. 36, No. 2).
Edward Yourdon and Larry L. Constantine. Structured Design. Prentice Hall, Englewood Cliffs, N.J., 1979.
There is an update to Visual Studio 11 that came out in early April that is available. You can find the details here:
If you haven’t been playing with Visual Studio 11 yet, I strongly encourage you to get it today. You can download it from here:
When you DO have it one of the first things you should do is turn on automatic checking for updates to extensions found at Tools | Options | Environment | Extension Manager:
Not only will this make sure you are notified about the latest and greatest version of your favorite extensions but it will also enable notification of updates to Visual Studio! We are now pushing updates to the IDE as extension-like elements. When you enable this feature, every time you start Visual Studio you will see a message whenever there is an update to Visual Studio that looks like this:
You can click on the bubble or, to get to updates manually, go to Tools | Options | Extension Manager | Updates | Product Updates:
You will see the update(s) available and can then click on the Update button for the items you want. In this case, when I clicked on update for the April 2012 fix for VS11, I received the download dialog:
Selecting Run began the installation process:
It finished smoothly and Visual Studio was updated easily.
Go out there and update your version of Visual Studio 11 if you haven’t done it already so you can get the most up-to-date goodies!
The new book is entering its final stages before we start work in earnest. After much discussion internally we have finally come up with a potential title for the new book and I wanted to get your thoughts. Let me preface this with the following: We wanted to depart from the “tips and tricks” moniker for the book as we feel it doesn’t adequately portray what the book does (or should do at least). With that said, the current thought on a title is (drum roll, please):
Microsoft Visual Studio Productivity Handbook
I really want your feedback on this one. Does it suck? Do you like it? Tell me your thoughts…
I'm happy to announce that the New Year marks the beginning of my endeavor to carry on Sara Ford's great work with Visual Studio Tips and Tricks for the Visual Studio product (http://blogs.msdn.com/saraford/archive/tags/Visual+Studio+2008+Tip+of+the+Day/default.aspx). After many discussions between us on how best to move the effort forward we decided that continuing the love with 2010 was a good idea. With Sara's help I have managed to get a good idea of her approach and added elements of my own style to the mix.
Additionally, in conjunction with Scott Cate (http://scottcate.com), I am pleased to say almost all tips will include a video showing the tip in action. Many thanks to Scott for stepping up and doing the past and future videos related to this series.
I haven't decided to crank out the book proposal yet for a new edition and probably won't for a while yet but am thinking the updated version will include versions 2005, 2008, and 2010 as well as (per Sara's suggestion) some new sections on extending Visual Studio with macros and the new extensibility model.
There was some debate over whether to wait until VS2010 launches or begin with the New Year. As you can see, I decided to begin on January 1. This is important for a couple of reasons:
1. The tips published until RTM will be based on Beta 2 and RC builds.
2. It is possible (though unlikely) some of the tips may not be valid in the RTM build when it ships. I will be retesting all tips when VS2010 ships to make sure they work as advertised :)
The plan is to have a tip a day posted on this blog with a few extra items thrown in for good measure. What you will see is a healthy mix of new tips in Visual Studio 2010 and some of the old favorites as well (tested to make sure they still work). To be absolutely clear: These are Visual Studio 2010 Tips and Tricks so what you will see are the details on how to leverage old and new content with our latest product. To get things started, and through the inaugural weekend, let's take a look at the #1 tip from Sara's Tips and Tricks:
How to behold the power of Incremental Search
Tip Code: vstipFind0001
Keyboard Shortcut: CTRL + I
Menu Command: Edit -> Advanced -> Incremental Search
Incremental search is a powerful search to use when you want to keep both your focus and your cursor in the editor when searching in the current document. It is powerful because it allows you to keep typing, meaning the search is driven by keystrokes. And you don't need to interact with any UI.
To conduct an incremental search, follow these steps:
Start typing the text you are searching for. You'll see the cursor jump to the first match, highlighting the current search string:
If you look in the lower-left corner of your screen you will see an indication that you are doing an Incremental Search:
Press Ctrl+I again to jump to the next occurrence of the search string:
Here are all the options you can leverage while in this mode:
Move to the next match in the file
Reverse the direction of the search
Remove a character from the search string
Stop the incremental search
In my travels across the country, with my fellow Evangelist, Clint Edmonson, talking about Visual Studio we often come across great stories to tell. One of our favorite true stories is of a customer that had a web application running very slow. We ran code metrics against it and, sure enough, the Page_Load event had 9,000 lines of code in it.
Naturally we were curious so we opened it up to see that it was basically the same if statement copied over and over. Apparently they needed to find out who was coming into the website in order to show customized content and the solution they came up with was this massive set of statements.
For better or worse we have all had code that gets copied throughout our solutions. Until now there was no tool to tell us there were copies and, instead, we had to rely on other metrics to hopefully reveal any code smells that lead us to duplicates. Now, however, we have the new Code Clone Detection (aka Code Clone Analysis) feature.
According to the documentation:
“Code clones are separate fragments of code that are very similar. They are a common phenomenon in an application that has been under development for some time. Clones make it hard to change your application because you have to find and update more than one fragment. Visual Studio can help you find code clones so that you can refactor them.”
You can find clones of specific code by selecting the segment you are interested then right click on the selection to choose Find Matching Clones in Solution from the context menu:
Visual Studio will search for code clones and produce the result in the new Code Clone Search Results window:
The original line of code is put in a group on its own and then all the matches are put into a different group. You can expand the groups to see the specific locations of the matches:
Also, you can double click on any entry in the list to go to the selection in your code file:
Besides looking for specific clones you can also look for code clones for the entire solution. To use this feature go to Analyze | Analyze Solution for Code Clones:
This creates a result set for the entire solution:
By default it groups and sorts the results by the strength of the match. Exact matches come first then those matches that may be close but not exact come next and so on. The terms you may see are Exact, Strong, Medium, and Weak.
Once you have the result set, there are a couple of ways you can compare them against each other.
If you have a comparison tool configured you can Right-click on any item and select Compare from the shortcut menu:
You would know if you have this feature available by going to Tools | Options | Source Control | Team Foundation Server and click on Configure User Tools.
If you don’t have a comparison tool you can do manual comparisons between two entries in the list. If the clones are in different files then you can just double-click each entry and it will open the file as well as highlight the entry that is duplicated as mentioned earlier.
You are probably curious as to what is found by this tool. The heuristics for finding clones will find duplicates even if the following changes have happened:
· Renamed identifiers
· Insert and delete statements added
· Rearranged statements
There are some rules for what is not found as well. I have taken this list from the documentation pretty much verbatim.
· Type declarations are not compared. For example, if you have two classes with very similar sets of field declarations, they will not be reported as clones. Only statements in methods and property definitions are compared.
· Analyze Solution for Code Clones will not find clones that are less than 10 statements long. However, you can apply Find matching clones in solution to shorter fragments.
· Fragments with more than 40% changed tokens.
· If a project contains a .codeclonesettings file, code elements that are defined in that project will not be searched if they are named in the Exclusions section of the .codeclonesettings file.
· Some kinds of generated code are excluded:
· *.designer.cs, *.designer.vb
· InitializeComponent methods
A settings file is available to configure this feature at the project level. Currently we have only announced the ability to do exclusions in the file but there will most likely be other elements that are added later on. The file is just XML with a .CODECLONESETTINGS extension. The only requirement for use is that the file exists in the top level directory of the project.
The base elements consist of a CodeCloneSettings element with an Exclusions child:
Within the Exclusions element you can have the following children:
This element is used to indicate files that should be excluded from analysis. Path names can be absolute or relative and you can use wildcards as well. So, for example, to ignore all the C# text template files that have been put in their own directory (called MyTextTemplates) you might have the following:
You can also exclude namespaces, types, and functions. Just like files these items can use absolute names or names with wildcards in them. Here is an example of what it might look like:
In the Tailspin Toys sample there is some generated code in the TailSpin.SimpleSqlRepository project that is the bulk of the duplications:
When I run code analysis, this is the result:
Code clone analysis doesn’t automatically know to ignore text templates so I would create an XML file called TailSpinRepository.codeclonesettings and insert an entry like this:
Now if I run clone analysis again here is what I get:
As you can see the results are significantly less than the first time the analysis ran. It’s common to create several exclusions in different projects to weed out noise in the analysis results.
Code Clone Detection is a great new tool to add to your arsenal for improving code quality. Combined with Code Analysis and Code Metrics, this will help quickly find potential issues.
Keyboard: F5; CTRL + F5Menu: Debug -> Start Debugging; Debug -> Start Without DebuggingCommand: Debug.Start; Debug.StartWithoutDebuggingVersions: 2008,2010Published: 11/1/2010Code: vstipDebug0037
While researching this one I came across a LOT of misinformation concerning what is actually happening here. There seems to be a great deal of confusion as to what is actually happening when you use Start Debugging (F5) versus Start Without Debugging (CTRL + F5):
Starting With Debugging
Let's start with the basics: When you press F5 (Start Debugging) in Visual Studio it launches your application, attaches the Debugger, and let's you do all the "normal" things you would expect:
According to the documentation (http://msdn.microsoft.com/en-us/library/k0k771bt(v=VS.100).aspx) here is what the Debugger does:
"The Visual Studio debugger is a powerful tool that allows you to observe the run-time behavior of your program and locate logic errors. The debugger works with all Visual Studio programming languages and their associated libraries. With the debugger, you can break, or suspend, execution of your program to examine your code, evaluate and edit variables in your program, view registers, see the instructions created from your source code, and view the memory space used by your application."
The Debugger: Release Builds
One popular misconception is the Debugger doesn't come into play for Release builds. This isn't true. Set a Breakpoint in some code for a Release build and then press F5 to see if is stops there:
Of course it does! The Debugger is attached! That is what is happening. Now, there are some things that aren't happening as well. For example, you can't use the System.Diagnostics.Debug class methods to send messages to the Output window since the compiler strips them out for Release builds:
Start Without Debugging
This is exactly what it sounds like. It starts the application WITHOUT THE DEBUGGER ATTACHED. That's it! Nothing else. It just doesn't attach the Debugger. Otherwise everything else is the same. So, the practical implications of this are obvious: Without the Debugger attached when the application runs it will not hit Breakpoints, emit Debug messages, etc. So now let's deal with the biggest myth about Start Without Debugging.
Myth: Start Without Debugging Creates a Release Build
Nope. It uses the build you are currently on. So if you are using a Debug build and you press CTRL + F5 then it will run that Debug build. The easiest way to test this is to use conditional compilation to see if you are using a Debug build:
In this example, the Console statement will run but the Debug statement will NOT run because the Debugger is not attached. So I will get this output:
And, if I attach the debugger after pressing CTRL + F5, to this process:
Then this is what I get:
The Debug messages haven't been stripped out because I'm using a Debug build of the application.
Okay, so the obvious question is "Why?". I mean, why would they give us this option? Well the most obvious answer is so we can run the application without having to hassle with disabling breakpoints, etc. to do a quick "Smoke Test" and see if it runs. There may be other reasons you have for wanting to run without the Debugger attached as well. So now you have a better idea of the difference between Start With and Start Without Debugging. Go forth and debug away!
This question came up the other day from Craig P. and I thought it was such a good one I wanted to blog about it. I think many of us take it for granted that upgrading from Access to SQL is a natural progression but we sometimes forget the "why" of it all. the bottom line is that sometimes the answer is to upgrade but sometimes the answer is to keep using Access. Making informed decisions is important and being able to convince management plays a critical role to your success. So with that I present two articles:
1) Microsoft Access or SQL Server 2005: What's Right in Your Organization?
2) And, to help compare SQL 2005 vs SQL 2008, "SQL 2005 vs. SQL 2008 Part 1"
Yes, you have to register at that last site unless, of course, you use something like BugMeNot.com: http://www.bugmenot.com/
Keyboard: CTRL + M, CTRL + M Menu: Edit -> Outlining -> Toggle Outlining Expansion Command: Edit.ToggleOutliningExpansion Versions: 2008,2010Published: 3/15/2010Code: vstipEdit0029
By default, Outlining is enabled in Visual Studio. It's the line you see with the boxes to indicate the status of the area (collapsed or expanded):
You can collapse areas of code to get them out of your way so you can focus on other areas. There are four ways to do it:
Once collapsed, the code area will look like this:
Windows: ALT + W, N (new window); ALT + W, V (new vertical tab group)
Menu: Window | New Window; Window | New Vertical Tab Group
Command: Window.NewWindow; Window.NewVerticalTabGroup
Versions: 2005, 2008, 2010
For quite some time you have been able to split your code windows horizontally (see http://blogs.msdn.com/b/zainnab/archive/2010/03/05/split-your-windows-vstipenv0004.aspx) but did you know there is a technique you can use to split your code windows vertically?
These techniques do not work on .ASPX files see http://blogs.msdn.com/b/zainnab/archive/2010/12/05/vertical-split-view-vstipedit0081.aspx
Also, these techniques will not work for .XAML files. To split them vertically click the Vertical Split button in the designer:
First, locate the tab for the file you want to split vertically:
Next, make a copy of the window by going to Window | New Window on your Menu Bar:
Finally, go to Window | New Vertical Tab Group to split the copies:
Now you have the code window split vertically in the IDE. Of course you could always rip one of the copies outside the IDE and vertically arrange them as well (http://blogs.msdn.com/b/zainnab/archive/2010/01/15/free-your-document-windows.aspx).