This tip is for C# developers only, unfortunately -- but it's the easiest way in the world to create an iterator. An iterator is any method that returns the "next item" in a series. The issue with an iterator is that you have to return a value when called and then pick up at the "next item" when called again.
The simplest iterator in the world is one that just counts from zero on up. In this example, for instance, x would first be set to 0 and then 1 and then 2 and then... you get the picture:
int res;
foreach (int i in Counter())
{
res = i;
}
Implementing that Counter method is easy if you use yield: Just insert the word "yield" at the start of your return statement to return the value and then pause your method at that statement until the next time it's called. When your method is called, your code will continue on from the statement following the yield statement.
The only wrinkle is that the method must appear in a method that's part of some iterator interface (e.g. IEnumerable). That means, to use the yield statement in the easiest way possible (and, when you're talking about the yield statement, you're aiming for "easiest way possible") you need to declare your method's return type as IEnumerable and call your method inside a foreach block. A version of the Counter method that would go from 0 to 2 would look like this:
public System.Collections.IEnumerable Counter()
{
yield return 0;
yield return 1;
yield return 2;
}
Each time the Counter method is called, the yield return statement will return the value and then wait to be called again before it will go on to the next statement.
A more complicated version would count up from 0 to the largest possible value that an int supports:
public System.Collections.IEnumerable CounterInfinite()
{
int i = 0;
while (i < int.MaxValue)
{
yield return i;
i += 1;
}
}
But the principle remains the same: Whenever your code is called, "yield return" something and then, in the next line of code, go on to get the "next one." If, in a Customers object, you wanted to create a property called Orders that lest a developer loop through all of the Orders for a the customer, you could use the yield keyword. In the property's getter, you would retrieve a DataSet and loop through the rows, returning an Order object created from the row at each yield return.
Here's similar code using LINQ to keep it short. The yield return inside the foreach loop returns an Order object and then waits to be called again before going through the loop to get the next Order:
public IEnumerable<Order> Orders
{
get
{
northwndEntities dc = new northwndEntities();
var res = from o in dc.Orders
where o.CustomerID == this.CustomerId
select o;
foreach (Order o in res)
{
yield return o;
}
}
}
A developer can now process your collection with code like this:
foreach (Order o in cust.Orders)
{
//do something with an order
}
Posted by Peter Vogel on 06/20/2011 at 6:13 AM8 comments
In our June Toolapalooza issue (
17 Free Tools for Visual Studio), we reviewed some of the best and most useful free tools for Visual Studio. One of those tools was smtp4dev, which allows you to quickly check the results of any email that you send from your application -- very useful in testing. But, as I noted in the article, I found smtp4dev to be... well, quirky, let’s say.
One of our readers came to my rescue and recommended Papercut as a great alternative. And he was right: I think I’m in love again (I create a lot of e-mail applications).
Downloading Papercut gives you a zip file containing a DLL, a config file, and the Papercut executable. Just drop these into any folder (though something in C:\Program Files would be most appropriate) and double click on the executable to run it. An msi would simplify installation, but not by much.
While it’s running, Papercut automatically picks up e-mail sent to the standard SMTP port (25) on any IP address: You just send mail from your application and switch to Papercut to review it. The user interface is clean and easy to use. An Options button lets you change the port being monitored and -- more usefully -- have Papercut minimize when it starts. When Papercut does minimize, it shrinks to the tray where you can re-open it to review e-mail by double-clicking on it. The tray icon displays a message whenever Papercut picks up some new mail so you can use this to test background processes as easily as foreground applications. Papercut gives you a full view of your mail: You can look at the full transmission (including headers) or just the body of the email. Papercut also keeps a log of all the activity it performs so, if something goes horribly wrong, you can trace back to see what happened.
How much do I like Papercut? Let me put it this way: I used the External Tools dialog on Visual Studio’s Tools menu to add Papercut to my menus.
Posted by Peter Vogel on 06/14/2011 at 5:58 AM0 comments
Sometimes you get null or Nothing passed to parameters for methods in your application. Sometimes that's not OK, but sometimes it is -- especially if you're accepting data from a database. If you're accepting a value parameter (like an integer), you may have been declaring your parameters as object so that you accept nulls. There is a better solution: you can add a question mark to your type declaration to indicate that it's OK to pass a null/Nothing value to that parameter:
Sub AcceptingParms(parmNullsOK As Integer?)
If parmNullsOK IsNot Nothing Then
Else
End If
End Sub
You're not limited to using the question mark in parameters or with the Integer/int datatype. You can use it on any value type where you're willing to accept a null/Nothing value. Do be aware, though, that these nullable types are a different datatype from their non-nullable cousins (i.e. int? is not int and Integer? is not Integer). So if you want to use a nullable value with a non-nullable value, you'll have to do a conversion:
Dim res As Integer
Dim num? As Integer = 2
res = Integer.Parse(num) + Integer.Parse(num)
What you're actually doing when you add the question mark to the end of your datatype is creating an instance of a reference class called System.Nullable<T>. To put it another way, int? is the same as System.Nullable<int>). The question mark is just shorthand for the longer declaration.
Posted by Peter Vogel on 06/07/2011 at 7:14 AM3 comments
In ASP.NET by using Views inside the MultiView you can, effectively, have several different pages inside a single ASPX file. Here's how to have those "additional pages" appear on your site's menus so that when a user clicks on a menu choice, the user not only goes to the right page but also has the page displaying the right View.
The trick here is to take advantage of a feature of the sitemap. In order to support the SiteMapPath control, each SiteMapNode in the in the sitemap must have a unique URL (or none at all). However that "uniqueness" includes whatever querystring you choose to include in the SiteMapNode's url attribute. There's nothing stopping you from having these two entries in your sitemap:
<siteMapNode url="~/Login.aspx?view=0"
title="Show View 0"
description="Display View 0 in a MultiView"/>
<siteMapNode url="~/Login.aspx?view=1"
title="Show View 1"
description="Display View 1 in a MultiView"/>
While the url attribute in these sitemapnodes point to the same page, they have different querystrings. If the page "MultiViewPage.aspx" has a MultiView on it, then this code in the Page_Load event will (when the user first sees the page) cause the View control specified in the querystring to be displayed:
if (!this.IsPostBack)
{
string pos = this.Request.QueryString["view"];
if (pos != null)
{
this.MultiView1.ActiveViewIndex = int.Parse(pos);
}
}
Posted by Peter Vogel on 05/31/2011 at 9:44 AM0 comments
Probably the only developers who care about this are the .NET developers doing Office development and who are upgrading projects to.NET 4. But if you do work with COM objects from code and are ever planning to move your projects up from .NET 3/3.5, this is worth knowing.
PIAs (Primary Interop Assembly) provide the information that supports interoperability between .NET and COM. PIAs for complex COM objects (think: Microsoft Word) are huge and kept in separate, monolithic assemblies. That means that when you use any member on your COM object, the whole PIA is loaded into memory (not to mention that the PIA was one more thing to be distributed).
Upgrading to .NET 4 can give you some significant benefits through the "NoPIA" feature (also called Type Embedding, but "NoPIA" just sounds cooler). With NoPIA, the necessary information to support COM interoperability is embedded into your compiled .NET code. Not only does that reduce the number of components to be distributed, only the parts of the PIA actually required by your application are incorporated into your code. If you only use a small part of a big COM object you could see significant size reductions in your compiled code.
The option is automatically turned on for new Visual Studio 2010 projects, but if you've imported a project from an earlier version of Visual Studio, you'll need to set it yourself. In your References list, select the reference to your COM object. Then, in the Properties window, find the Embed Interop Types property and set it to True.
Posted by Peter Vogel on 05/24/2011 at 9:03 AM0 comments
Prior to .NET Framework 4, threading used a locking mechanism that added to the thread overhead. In .NET 4 the locking mechanism is eliminated. On top of that, threading integrates better with garbage collection, reducing the time required to clean up after a thread finished running
Putting those two changes together means that just moving your multi-threaded application to .NET 4 can improve its performance. In addition, there was a bug in prior versions of .NET around aborting threads that issued locks. If you aborted a thread at the wrong time (when a no-operation instruction that was part of the generated IL code was being processed), the lock might never be released. If you've been trying to figure out why your multi-threaded application's performance degrades over time, it's a sign that the upgrade to .NET 4 might not be an optional activity.
If you've got time, after you upgrade, you should consider rewriting your code to use the Task Parallel Library (TPL). In previous versions of .NET 4, while you could queue up threads, you couldn't provide much information to .NET about which threads were most important. In the absence of that information, .NET treated all queued threads equally.
The TPL allows you to provide more information to .NET's scheduler to improve how your threads are handled. All by itself, the TPL gives you the ability to sequence tasks by having one task kick off as soon as another completes. See my VSM feature article on PLINQ and the TPL for more information.
Posted by Peter Vogel on 05/17/2011 at 7:24 AM0 comments
By default, if you open a new file you get a new tab in your document window. After awhile, you can end up with forty two open tabs. To get things back under control, you have to use the Windows | Close All Documents choice, or right-mouse click on the one tab you want to keep open and select the Close All But This option).
If you want, you can have Visual Studio open any new document in your current window (provided that the current window has no unsaved changes). So, when you double-click on a file in Solution Explorer, the current window's content is replaced with the content of the file you just opened. You only get a new tab if the file in the current window has unsaved changes.
To turn this feature on, go into Tools | Options and in Environment | Documents check the "Reuse current document window, if saved" option.
Taking advantage of the feature does require a different mindset. When I use this feature, I start off by opening new tabs until I do a build or a debug (that saves all of my current changes). After that, when I open a new file, that new file replaces the file in the current tab. I find that I start searching my currently open tabs for "Which file do I want to get rid of?" I then select that file's tab and open a new file. It keeps the number of tabs under control, but it is a different way of working.
Do you have a Visual Studio tip, you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 04/26/2011 at 1:42 PM0 comments
I never delete code -- you never know when you might want it back. So I spend a lot of time commenting out code. I do this so often, and mousing up to the menu takes so long, that I've memorized the keystroke combination for commenting/uncommenting code. It’s actually one of the few keystroke combinations -- other than Undo -- that I remember.
To comment a group of lines, first select the lines. Then, holding down the Control key throughout, press K, then C. To uncomment, hold down the Control key and press K, then U. (These two stroke combinations are called "chords.")
Do you have a Visual Studio tip, you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 04/19/2011 at 6:15 AM57 comments
You can get Visual Studio to create classes for managing (or, at least, observing) computer resources for you. In Server Explorer, under the Management Classes node, you'll find a list of "things you can manage." This includes desktop settings, processes/threads, and printers (!!), among other resource.
Find the item you want, right-mouse click on it, and select "Generate Management Class" to have Visual Studio generate a management class for you.
For instance, right-mouse clicking on My Computer in Server Explorer generates a class called ComputerSystem (in the namespace ROOT.CIMV2) with all sorts of read/write properties for changing settings on your application's host computer. It also includes many read-only properties for checking the computer's state. Several enumerations are included to allow you to write readable code.
There's another way to get Visual Studio to create a class for managing computer resources for you. If you work with Message Queues (or any of the other things listed in Server Explorer), Visual Studio is more than willing to generate a control that you can use from your code to manage that resource.
Just click on the item in Server Explorer and drag it onto a form (or any other design surface). Dragging a Message Queue from Server Explorer gives you a control dedicated to that queue with Receive and Send methods (and a ton of other methods and properties). You can do this with anything listed under the Services node or any of the categories listed under Event Logs.
You can use this feature in a class library, even though classes don't normally have a design surface. In Solution Explorer, right-mouse click on your project and select Add Component, instead of your normal Add Class. That will give you a "class with a design surface" that you can drag Server Explorer resources onto.
Don't go nuts! You can drag some but not all from Server Explorer -- see http://msdn.microsoft.com/en-us/library/84s2c1k0.aspx for a list of what you can and can not drag.
Do you have a Visual Studio tip, you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 04/12/2011 at 6:26 AM0 comments
I'm constantly creating simple projects to test out some idea or as part of reviewing a new tool. By default, as soon as you create a new project, Visual Studio automatically saves the project file and, well, everything else. After awhile, I end up with 142 projects with dummy names ("TestTool", "TestTool1", "Experimental", "Experimental1", and so on).
You can turn off this behavior so that projects aren't saved until you tell Visual Studio you want them saved (you will be asked when you exit the project). Go to Tools | Options and under Projects and Solutions | General uncheck the "Save new projects when created" option.
This doesn't work for all project types (it has no effect on ASP.NET or Silverlight projects, among others, for instance). Fortunately, it's easy to tell whether it works on the project you're creating: You won't have the Location textbox at the bottom of the New Project dialog. Don't Panic! You'll get a chance to save your stuff when you leave the project. Or, if you've done everything you need to do with the project, to not save your stuff later.
For any project that you do want to keep, though, it would be a good idea to do a Save soon after starting the project. If you don't do a save and Visual Studio crashes, you may not be able to recover your project.
Do you have a Visual Studio tip, you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 04/05/2011 at 6:36 AM0 comments
SharePoint developers working in Visual Studio 2010 know that GUID collisions can be a needless nuisance. Brian Watts sent along this tip that he got from one of Doug Ware's
tutorials on SharePoint. Brian adds a pre-deployment command to his Visual Studio build-deploy-debug process that deletes and recreates his SharePoint site before he does any testing. Brian says he can't remember the last time he had a problem with a GUID clash.
To make this happen, in your SharePoint 2010 project, go into the Properties window, select the SharePoint tab, and add the following code to the pre-deployment Command Line box at the top of the window:
stsadm -o deletesite -url <url for his site>
stsadm -o createsite -url <url for his site>
-owneremail <your email>
-ownerlogin <your admin id, including the domain name>
-siteTemplate "STS#1"
-description "A test site"
-title "Test Site"
Brian says it might be adding a couple of seconds whenever he presses F5, but that delay is more than worth the benefits of avoiding any problems.
Do you have a Visual Studio tip, you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 03/29/2011 at 10:42 AM0 comments
While all of the tool windows in Visual Studio (Solution Explorer, Properties, Debug) are wonderfully useful, the main editor/document window where your code lives is the one that matters.
You can instantly give yourself a document window that completely fills Visual Studio by selecting Auto Hide All from the Windows menu. This causes every (every!) tool window to turn into little labels hugging the borders of Visual Studio and popping out only when you want them (or when Visual Studio thinks you should want them). If you can't find Auto Hide All, it's because you've already closed or hidden your tool windows.
There is a downside to this: There's no "Restore to my last setting" option on the Windows menu so, you'll have to get used to having every (every!) tool window in autohide mode. You can get back to the default window layout for your configuration of Visual Studio by selecting Reset Window Layout from the Windows menu, but you won't get any customizations you've made to that setup.
There doesn't seem to be a way to save your favorite layout as the "default layout" that the reset menu choice restores. The only way to get back to your personal settings would be to have exported your settings at some point in the past and re-import them using the Tools | Import and Export Settings menu choice -- which seems like an awful lot of work (and not very speedy, either).
[Click on image for larger view.] |
| Figure 1. Big Editing Window. Auto Hide All opens up all the interior space inside the Visual Studio window for you to edit code. |
But as I said, you get all of that editing space....
Do you have a Visual Studio tip you'd like to share? Send it to me at phvogel@1105media.com.
Posted by Peter Vogel on 03/22/2011 at 6:40 AM8 comments