Monday, March 31, 2008

VS Snippet: On-demand getter

I often use base page classes in my web apps. On these classes I put read-only properties for access to business layer classes. I typically set these getters up to do on-demand (or "lazy" instantiation) because not all pages will use the various business class instances that are available. Instead of creating them all on class construction or page load, the get created as needed. After figuring out how to fix the "prop" shortcut to work the way I needed, I realized it made sense to create a snippet for on-demand properties. Now I simply type "propod" and I get this:

private object myVar;

public object MyProperty
{
get
{
if(myVar == null)
{
myVar = new object();
}
return myVar;
}
}

Here's a Visual Studio shortcut snippet file XML for it. Just save it to a .snippet file in your visual studio snippets directory (i.e. C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#):

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>propod</Title>
<Shortcut>propod</Shortcut>
<Description>Code snippet for on-demand read-only
property and backing field.</Description>
<Author>Peter Lanoie</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>object</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
<Literal>
<ID>field</ID>
<ToolTip>The variable backing this property</ToolTip>
<Default>myVar</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[private $type$ $field$;

public $type$ $property$
{
get
{
if($field$ == null)
{
$field$ = new $type$();
}
return $field$;
}
}
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

C# "prop" shortcut in Visual Studio 2008

Anyone who builds classes in Visual Studio hopefully uses the "prop" shortcut to generate a property with its backing variable. Just type "prop" and hit tab twice and you get this:


private int myVar;

public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}


Update the fields and away you go. This is a major time saver. I was disappointed to see Microsoft change its behavior in the 2008 upgrade. The new behavior is to generate an automatic property:


public int MyProperty { get; set; }


I learned recently where these shortcuts, or snippets are stored. It turns out it's pretty easy to modify or add to them. In Visual Studio 2005, you can find them here:

C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\1033\Visual C#

For 2008, here:

C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#

It appears that there aren't that many changes between versions. Of course, the one they changed is the one I suspect most of us use the most often. Shame on them.

I'm not here to argue the merits of full vs. automatic properties. I'm all for automatic properties. The problem happens when we return from VS2008 "Hello World" example to our real world code base. VS2008 happily upgrades an assembly I created in VS2005 but keeps it backward compatible. However, it seems that it is not smart enough to recognize that this assembly is targeting the 2.0 framework or rather that the project will still be used in VS2005. (I suppose one might argue "how would it know?") All those automatic properties won't compile in the 2.0 compiler while the 3.0+ compilers expand them out automatically.

So I decided that rather than cursing every time I have to manually expand a property I would instead fix the problem. Simply manipulating the .snippet files in the directory mentioned earlier does the trick.

I copied the "prop" snippet from the VS2005 directory into that for 2008 and renamed the "prop" snippet in 2008 "aprop" ("propa" was taken). You just need to be sure you edit the snippet XML to rename the snippet's shortcut and name as well, they are the values that show up in the IDE.

An interesting side note to this: Having forgetting to update the snippet shortcut and name in its XML, I tried it out and discovered that VS recognizes the duplicate names. It prompts you with "Multiple Snippets" and you must make another choice. Neat. Someone was thinking.

Thursday, March 20, 2008

Old hardware + young kid = tearful parent

It all started with Alex. A few days ago my friend Alex asked me if my web sites were still down. You see, I host a couple of web sites on an old machine at home. It's mostly just personal stuff but there's some (very little really) professionally relevant content on one of the sites. Unfortunately, the machine is starting to break down. The fan squeaks and rattles on occasion, I've had a hard drive inexplicably fail and then return to life and the board is just old and slow for what I need it to do. Despite this, yesterday morning I turned the server back on.

Some time in the middle of the morning I remembered that I wanted to check to see if the machine had actually gotten up and running, so I hit the sites on it, one of which is my personal photo browser. In doing this, I started browsing early photos of my son. Then the Dan Fogelberg song "Longer" popped into my head. So I downloaded the MP3 from the music collection also hosted on this box at home. I listened to it a few times and got to thinking about my kid. I can't say that I've ever been a particularly emotional person, but it's amazing what a kid will do to you. I'm fortunate to have a private office tucked away in a quiet hallway.

So yesterday evening, after putting Spencer to bed, I put this together:



Now I just need to put this video into a digital photo frame that I can hang above Spencer's time out chair to help dissipate the frustration a 2-year-old can create.

Thursday, March 13, 2008

abstract VS. virtual explained

Something I struggled with for a while when first getting into C# was the difference and use of the 'abstract' and 'virtual' keywords. Here is my simple explanation:

abstract - Members modified by this keyword MUST be defined in an abstract class and be implemented on any concrete (non-abstract) class that extends the class the member is defined on. (This corresponds to the 'MustOverride' keyword in VB.NET.)

virtual - Members modified by this keyword CAN be overriden on a concrete class that extends the class that defines the member. (This corresponds to the 'Overridable' keyword in VB.NET.)

C# Example:

abstract class AbstractClass
{
protected void NotModifiedMethod() { }
protected abstract void AbstractMethod();
protected virtual void VirtualMethod() { }
}

class ConcreteClass : AbstractClass
{
//This HAS to be overriden because it's abstract
protected override void AbstractMethod() { }

//This CAN be overriden because it's virtual
protected override void VirtualMethod()
{
base.VirtualMethod();
}

//You CAN NOT do this, because NotModifiedMethod is not
//marked as abstract or virtual
protected override void NotModifiedMethod() { }
}


VB.NET Example:

MustInherit Class AbstractClass

Protected Sub NonModifiedMethod()
End Sub

Protected MustOverride Sub MustOverrideMethod()

Protected Overridable Sub OverridableMethod()
End Sub

End Class

Class ConcreteClass
Inherits AbstractClass

'This HAS to be overriden because it's marked MustOverride
Protected Overrides Sub MustOverrideMethod()
End Sub

'This CAN be overriden because it's marked Overridable
Protected Overrides Sub OverridableMethod()
MyBase.OverridableMethod()
End Sub

'You CAN NOT do this, because NotModifiedMethod is not
'marked as MustOverride or Overridable
Protected Overrides Sub NonModifiedMethod()
MyBase.NonModifiedMethod()
End Sub

End Class