Posted on August 28, 2008 10:45 by swilliams

Design matters. The User Interface of an application, be it web or desktop, is one of the most, if not the most, crucial part. Why? Because to the client and/or customers, it is important to them, though they may not know it.

It's been said before, but to the customer, the UI is the application. You might have developed the fastest, most efficient algorithm, but if the user cannot use it, then they just won't.

To be clear, "design" is not necessarily the aesthetic look and feel of an application. Pretty and shiny contribute to the overall sense of design, but do not make up for shortcomings. In fact, there are plenty of command line driven apps that have great design. They ain't pretty, but work great. And once you move a little bit up the learning curve, they become second nature.

EeyoreGood design can be obtained by non-artistic types. One of the most common myths I hear is that people think you have to be be "A Designer" to do good work. The most common response I hear for  a terrible work is "Well, I'm not a Designer."  Yeah, that might be true in HR's filing cabinet, but it just strikes me as a lazy excuse. Or something that Eeyore would say, "Oh well, I'm no good at this. Why even try? I'll just stick to aquamarine and fuchsia." No, your job title might not say "Designer," but it also probably doesn't say DBA, yet you probably have some working knowledge of how SQL works right?

There is a talent aspect to it, but like everything else, talent is worthless without the work to reveal it. And talent is kind of like temperature anyway; there is an absolute zero, but it cannot be achieved in nature (even with quantum effects). In reality, even the most inept can achieve adequate, or even good, design if they apply enough effort.

Where does good design come from then? John Gruber points out that too many people believe that design is just something to worry about at the end of a project. If you say, "Oh, all we have left to do is the UI," then you might as well just drive it off a cliff right then and there.

In the end, a good design ultimately benefits you. The work you do reflects who you are and how your clients/employers see you. And their first impression is the design of an application, so doing a shoddy job is only a disservice to you. It is not easy, but what in software development truly is?



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on August 27, 2008 17:34 by baugustine
 

Interesting issue Shawn and I ran into today with the <script> tag in ASP .Net. A page was defined with <script> tag that was closed with a /> instead of </script> as shown below.

 

<script language="javascript" src="myJavaScripts.js" type="text/javascript" />

 

And any time a control on the page did a post back it started throwing java script errors such as "Object Expected". Other variants could be "__doPostback not defined" but I did not see that error. Anyway the culprit was the /> closing tag. So to fix the error I had to end the <script> tag with </script> tag instead of />. So changing the above statement to

 

<script language="javascript" src="myJavaScripts.js" type="text/javascript"><script>

 

fixed the error.

 

Incidentally this worked also.

 

<script language="javascript" src="myJavaScripts.js" type="text/javascript" />

<script></script>

 

Go figure.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on August 17, 2008 13:35 by baugustine
 

Team Foundation Server (TFS) has a great feature called shelving. It allows you store a copy of your source code changes on the TFS server. Please note that this is different from checking in the code, because the copy is set aside temporarily or shelved under your userid. Since the code is not checked in you can be confident it is not going to break your team's nightly or continuous build.

 

There are several ways to shelve your changes. The easiest way to do it is from Visual Studio, click on your Pending Changes window, and select the files and click Shelf button. In the dialog window that opens up enter a Shelveset Name and click Shelve. If you give a Shelveset Name that is already existing it will ask for confirmation to overwrite it.

 

For unshelving, open Pending changes window in Visual Studio and click Unshelve. By default it will show you all the shelvesets for your userid. Click on the self set name from the list and click Unshelve. It will bring down your shelved code files to your local workspace automatically check it out from the TFS server.

 

For more ways including command line to do shelving and unshelving look at the MSDN documentation here.

 

Some of the uses of Shelf feature are:

  • Set aside temporarily a feature or some code change that you are working, because you are now assigned a different task or a bug to fix.
  • Collaboration on a code change. Say you are working on a code change and you need some extra information from another team member to finish it. You can shelf your code and have your team member unshelf it and provide the extra information and check it in.
  • Use it for code review purposes before checking it in for build.
  • Use it as a personal code change backup. I normally give a shelfset name of bkp (because I am lazy), and allow the confirmation dialog to overwrite my existing backup. You still have to remember to manually do this though. I have made it a practice to do this before I leave for the day. May be I will automate this some day and blog about it.

For more information about shelving and unshelving look at MSDN documentation here. There is also a 10 min video here that gives you a hands on approach.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 26, 2008 21:47 by swilliams

Delegates have come a long way since they were introduced in .NET 1.0. Back then they were only a way to refer to existing methods as variables. 2.0 allowed methods to be inlined, making them "anonymous." The 3.5 Framework does not introduce any new concepts regarding delegates, but it makes writing them much, much quicker and cleaner.

Let's reuse the example from the last post. C# 2.0's syntax for anonymous methods looked like this:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        item.BackColor = index % 2 == 0 ? Color.Red : item.BackColor;
    });
}

The HighliteEven() method can be written with C# 3.0 as:

public void HighliteEven() {
    this.ActOnListView((x, y) => x.BackColor = y % 2 == 0 ? Color.Red : x.BackColor);
}

Whoa, where did that => thing come from? That's the new shorthand for creating an anonymous method. All it does is compresses delegate(Type object){ into something smaller. The (x, y) parameters do not need Type declarations because they are inferred from the delegate's signature as a ListViewItem and a Int32 (you'll even get intellisense on them).

This is what allows you to use all of the slick extension methods added to the standard collection classes:

List<string> stuff = new List<string>();
if (stuff.All(s => s.Length > 10)) {
    Console.WriteLine("all strings have at least 10 characters.");
}
string[] myName = stuff.Where(n => n.StartsWith("Scott"));

Single object parameters do not need parentheses, and delegates with no parameters use empty ones: ().

This type of expression is often called a Lambda. Technically, you can have multiple line lambdas, the convention is to stick with a single one1. Multiple lines of code with this syntax can quickly become messy and hard to read. Stick with the old delegate() { } syntax instead if you need it.

[1. I'm not even going to show or link to the syntax, since you shouldn't use it.]

If you are familiar with Python or Ruby (and others) this style should be familiar to you.

	# a lambda in Python
	sq = lambda x: x * x
	sq(5)
	# returns 25

	# a lambda in Ruby
	sq = lambda {|x| x * x}
	sq.call(5)
	# returns 25

.NET also provides a few prefab helper delegates. Action was provided in the 2.0 framework. It's signature looks like this:

public delegate void Action(T obj);

It has a few overloads to take up to four parameters. So, our sample code up top can be rewritten as:

private void ActOnListView(Action<ListViewItem, int> action) {
	// snip
}

Removing the ItemAction definition.

For methods that need to return something, .NET 3.5 offers several versions of a delegate called Func. The most basic is Func<TResult>(), which takes no parameters and returns an instance of whatever TResult is set to. Func<T, TResult> takes a single parameter, of type T, and also returns a TResult. Like Action, Func provides overloads for up to four parameters. These can all be backported to .NET 2.0, since they don't use any 3.5-only features:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T obj);
// and so on

The various forms of Func are used throughout the LINQ enabled extension methods of the 3.5 Framework.

The single biggest thing to be aware of is that overuse of delegates makes code difficult to read, especially for the neophyte. If you have a particularly hairy situation, say one that has three or more nested generics and a few lambdas, all on one line, consider splitting it apart in order to increase readability. The compiler won't care, but maintainers will appreciate it.

If you have never encountered them before, delegates can feel a little awkward at first, but once you get used to them, especially with C# 3.0's lambda syntax, you won't want to go back.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 26, 2008 11:47 by baugustine

Most of us application developers have worked with SQL Server databases and especially tables with IDENTITY property. We have all written stored procedures to insert records into tables with columns that have IDENTITY property set.

In case you are not familiar with IDENTITY property, this property can be set on a column that has a data type of decimal, int, numeric, smallint, bigint, or tinyint. When this property is set SQL Server automatically populates that column with a next higher number in the sequence when a record is inserted. So it has been somewhat of a common practice for application developers to set the IDENTITY property for an Id column of a table and let SQL Server manage the unique primary key values. More information about IDENTITY property can be found here

Normally one of the requirement when you write a stored procedure to insert a record into a table with IDENTITY column is that you will have to pass the Id value of the newly created record back to the application. Lot of developers use the @@identity variable in SQL Server to do that. And most of the time this will work because the @@identity variable holds the last identity value generated by the insert statement. Run the sql1.sql file from the attached zip file to see this working.

So far so good. Now all that is needed for this nicely working proc to fail to return the correct Id value is to add a trigger to our table, and that trigger inserts a record into another table (say an auditing table) which also happens to have a column that has its IDENTITY property set. Run the sql2.sql file from the attached zip file to see this behavior.

So why did the incorrect id values are returned after adding the trigger. The reason is that @@identity does not have a concept of scope. It always returns the identity value of last inserted record in the database. In this case it happens to the audit table record that got inserted last. So to overcome this behavior we need to modify the proc to use the scope_identity() function to return the last identity value instead of the @@identity variable. Run the sql3.sql file from the attached zip file to see the modified proc and the correct behavior.

So always use @scope_identity() function in your insert proc to return identity column values even though you may not have triggers on your table during development. Because adding a trigger on your table is beyond your control. All it takes is for your proc and application to not work properly or even worse cause data corruption is for someone else to add a trigger on one of your tables for some reason or the other.

ScopeIdentity.zip (1.70 kb)



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 24, 2008 10:13 by swilliams

Back in Part 1, we covered the history of Delegates in the .NET Framework. As stated, in 1.1, they were a little too confined to be exceptionally useful. However, in the 2.0 Framework, Delegates were given the ability to be "Anonymous" and could be created on the fly. This allows for more elegant coding, and serves as an introduction to some concepts previously relegated to Functional Programming.

First, an example. In the previous post, this was our basic demonstration of a delegate:

public delegate void SomeFunction(int num);

public void PrintHello(int num) {
    for (int i = 0; i < num; i++) {
        Console.WriteLine("Hello."); 
    }
}

public void Main() {
    SomeFunction func = new SomeFunction(this.PrintHello);
    func(10);
}

Anonymous Methods mean that we do not have to define the PrintHello method as a part of the class, it can be created inline:

public delegate void SomeFunction(int num);

public void Main() {
    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine("Hello.");
        }
    };
    func(10);
}

This in and of itself is useful; it cuts down a few lines of code, but doesn't necessarily add too much value.

Enter Closures. A Closure is "a [method] that is evaluated in an environment containing one or more bound variables." (I'll use OO terminology since this is C# related). What this means is that an anonymous method can refer and use variables defined in the scope surrounding it. Thus:

public delegate void SomeFunction(int num);

public void Main() {
    string s = "This is what will print.";

    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine(s); // not defined in the delegate, but still valid
        }
    };
    func(10);
}

This of course begs the question of the ages, so what? Why would I possibly want to do something like that? Well, for a simple example, let's say you have a collection of items, say, the items in a ListView, and you have a bunch of operations you want to perform on them at different times. The non-delegate way would be to have separate methods that iterate through the list and do its thing.

public void HighliteEven() {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem li = this.listView1.Items[i];
        if (i % 2 == 0) {
            li.BackColor = Color.Red;
        }
    }
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    foreach (ListViewItem item in this.listView1.Items) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    }
    return items;
}

These are only two methods, but it's not uncommon to have upwards of a dozen, depending on how robust the UI is. If you have an ExtractLong, there's a good chance you'll need an ExtractShort, and probably more ExtractX methods too. Already you can see code duplication in the loops. Anonymous methods let you refactor this code to:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (index % 2 == 0) {
            item.BackColor = Color.Red;
        }
    });
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

This is better, but we can refactor the Extract method even more. .NET 2.0 also introduces a special delegate called Predicate<T>. If you have used the Array.Find method before, you've used Predicate<T>. A predicate simply executes an expression that returns a boolean. In Array.Find()'s case, it evaluates the object at each index of the array. If the object passes the test provided, it adds it to the return set.

We can use the same idea here to create a generic Extract method which we can give any number of comparers, greatly shortening each ExtractX method.

private List<ListViewItem> Extract(Predicate<ListViewItem> comparer) {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (comparer(item)) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

public List<ListViewItem> ExtractLong() {
    return this.Extract(delegate(ListViewItem item) {
        return item.Text.Length > 50;
    });
}

Making an ExtractShort method is just another 3 liner, who's payload is return item.Text.Length < 5; So, rather than having 8 lines of code (at least) per Extract method, you can have 3, which can be a huge savings, and makes testing far easier.

These concepts, and the syntax, may look a little intimidating, but once you have used them for a little bit, you won't want to go back. In the next post, I'll cover the updates to .NET 3.5, and show similar features in a couple other languages.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 23, 2008 15:08 by swilliams

I gave a presentation last night on the topic of improving web design for developers. On the topic of CSS I gave a very simple demonstration on using a non-table based layout. It went well over all, but I didn't have a ton of time to get it perfect and resulted with this.

It works, but wasn't the best I could do (the right column noticeably doesn't extend to the bottom of the content). Christian asked a great question about this, but my brain froze and I wasn't able to come up with a quality answer. Of course this one detail plagued me through the night.

Well, the answer is very simple. Wrap the two columns in a container element (another <div> in this case). Set the overflow property to auto or hidden, adjust the width, accounting for padding, and use the same background color as the sidebar. And presto, you get what I meant to do.

If you'd like to see the markup and style, just view the source of the page.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 18, 2008 15:04 by swilliams

Confession time: I love Panic software. They put tons of effort into the UI of their products, and it shows. Even their website shows astonishing attention to detail, and web design isn't even a service that they offer. What gets me the most are the sliding panels on the page for Coda. I peaked at the source code for it and saw:

// Not for redistribution

Hrmph. And then I thought that I could probably reverse engineer what they were doing without copying and pasting their code. Just to be clear, I did not copy a byte of their code; everything here was written entirely by me (except in one case where labeled). To do some of the lifting, I used the Prototype JavaScript library, though you could just as easily do it with JQuery, YUI, or no library at all.

First, the Markup

This is the simplest part. The tabs are just a horizontally positioned list with the bullets removed. And the panels are divs floated sequentially. The idea is that there is a "window" div that displays one of the divs behind it. When a link is clicked, the floated divs slide in the proper direction.

scroller_image

Here is the markup to make it happen:

<div id="main">
    <ul>
        <li><a href="#" rel="scroll">Panel One</a></li>
        <li><a href="#" rel="scroll">Panel Two</a></li>
        <li><a href="#" rel="scroll">Panel Three</a></li>
        <li><a href="#" rel="scroll">Panel Four</a></li>
    </ul>
    <div id="scroll_container">
        <div id="scroller">
            <div>
                <h1>Panel 1</h1>
            </div>
            <div>
                <h1>Panel 2</h1>
            </div>
            <div>
                <h1>Panel 3</h1>
            </div>
            <div>
                <h1>More</h1>
            </div>
        </div>
    </div>
</div>

The only other thing worth mentioning is the rel="scroll" attribute on the anchor tags. This is just used to identify that these links cause a scrolling action to occur, and are used by the JavaScript to easily grab them.

The Style

Styling the HTML isn't too tricky, though there were a couple of small gotchas. My first thought was to set the position of scroller to relative and then use the JavaScript to adjust its left property. This would have worked, but then IE displays all of the scroll panels even if scroller's overflow is set to hidden.

After a bit of snooping I found that I could get the same behavior by adjusting the scrollLeft property on scroller. This manipulates the [invisible] scrollbar.

Scroller's width is large to accomodate all the panels, but could be set to anything greater than or equal to the aggregate width of the panels.

div#main
{
    width: 600px;
    margin: 0 auto;
    height: 800px;
    overflow: hidden;
}
div#main > ul
{
    margin: 0;
    padding: 0;
    width: 100%;
}
div#main > ul li
{
    font-size: 1.4em;
    margin-right: 20px;
    display: inline;
    list-style-type: none;
}
div#scroll_container
{
    width: 600px;
    overflow: hidden;
    height: 740px;
    background: #eee;
}
div#scroller
{
    width: 5000px;
}
div#scroller > div
{
    width: 600px;
    height: 740px;
    float: left;
}

JavaScript - where the magic happens

I took an iterative approach for the JavaScript. First, the most basic way to get "sliding" functionality. The initial design didn't even slide at all, it just moved the panels without an animation.

var scroller = function() {

    var scroll = function(index) {
        var totalOffset = index * scroller.scrollPanelWidth;
        var scrollee = $(scroller.scrollPanel);
        scrollee.scrollLeft = totalOffset;
    }

    var getScrollLinks = function() {
        var links = $$('a[rel=scroll]');
        links.each(function(elem, index) {
            elem.observe('click', function() {
                scroll(index);
            });
        });
    };
    
    return { 
        scrollPanel: '',
        scrollPanelWidth: 0,
    
        init: function(panel, panelWidth) {
            scroller.scrollPanel = panel;
            scroller.scrollPanelWidth = panelWidth || 600;
            getScrollLinks();
        }
    };
}();

This does exactly that. Some of the conventions I'm using here may seem a little weird, but it allows the scroller object to have private fields. To learn more about it, see here.

You can see this in action here.

Functional, but not fancy. I was going to use Script.aculo.us to do the animation, but it does it using the position: relative method described a few paragraphs ago, making IE render incorrectly. Which is kind of a bummer.

So, we'll have to animate this by ourselves. I arbitrarily decided that 500 milliseconds was an adequate time for the animation to take, in 25 frames (for simplicity's sake, pick a number that divides the duration evenly). To accommodate for these values, a couple of properties were added to the scroller object and the scroll() function now does the animating:

    var currentPosition = 0;   
    
    var scroll = function(index) {
        var totalOffset = index * scroller.scrollPanelWidth;
        var desiredOffset = totalOffset - currentPosition;
        var scrollee = $(scroller.scrollPanel);
        var tick = scroller.scrollTime / scroller.ticks;
        var timeIndex = 0.0;
        var inter;
	    
        function animate() {
            timeIndex += tick;
            var delta = desiredOffset / scroller.ticks;
            if (timeIndex > scroller.scrollTime) {
                clearInterval(inter);
                currentPosition = scrollee.scrollLeft;
                return;
            } 
            scrollee.scrollLeft += delta;
        }
        
        inter = setInterval(function() { animate(); }, tick);
    }

See it in action here.

With each tick of the timer the scroller div is moved a little bit in the proper direction. Since the duration remains constant, this has the neat effect of scrolling divs quicker the further apart they are.

At this point we could pat ourselves on the back and call it a day, but there is still a little bit more we could do. If you'll notice in Panic's design, the animation starts slowly, speeds up, then eases into the final position. Kind of like a train leaving the station, and then arriving at the next stop. Script.aculo.us's Effect.Move has the same property. It is these little things that really amp up the aesthetics of an app.

comparison How did they do it? Math! A sine curve has the function of what we're looking for. Our current example has a linear progression. Meaning each tick moves the scroller the same amount. With a sine curve, we get the behavior that Panic and Script.aculo.us have.

Since I haven't actually calculated the sine of anything since school, I decided to just steal borrow someone's code. As mentioned, Script.aculo.us has a sinoidal function. But grabbing a 100k library for a 3 line function is just silly, so I copied it to my own file directly.

var sinoidal = function(val) {
   return (-Math.cos(val * Math.PI) / 2) + 0.5;
}

sinoidal returns a value between 0 and 1, so we just need to multiply it by our desiredOffset to get our delta and tweak how the scrollLeft moves.

var delta = sinoidal(timeIndex / scroller.scrollTime) * desiredOffset;
/* ... */
scrollee.scrollLeft = currentPosition + delta;

And voila, smooth and fancy animation.

Lastly, I created a simple locking mechanism to keep the scroller from getting confused if a link is clicked before the animation is finished. There is still probably work left to be done, but that goes beyond the scope of what I wanted to discuss. So go forth and make great apps!

See the final example in motion.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 30, 2008 10:26 by lbrown

Ever wonder how that magical tag called ‘[Serializable]’ placed at the top of a class enables it to be deconstructed into XML that can be tranmitted through firewalls or persisted in a files or database tables? Not to get too technical but attribute classes are embedded into the tagged classes’ metadata at compilation and can be reflected on to perform any function you desire. 

The following example provides a real world scenario where custom attributes can enhance one’s  coding experience.  I can’t tell you how many times I have to use stored procedures that have a million parameters each having the capacity to be null.  Think of a search procedure that has ten criteria.  If I was coding this with the SqlCommand class, I would have to write a method that creates each SqlParameter and populates it with DBNull or some value. There are over ninety nine combinations in this scenario.  That really cuts into my ebay time.

If I wrote an attribute that could turn a class into a SqlCommand with populated values and could be serialized in session or view state and reduce my time coding, life would be wonderful.  In addition, if I wrote a tool that generated the code for the attributed class, my evil plan to do no work would be complete!

I have attached a solution that contains all the code mentioned above.

AtrributeSolution.zip (51.43 kb)



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 25, 2008 10:15 by lbrown

Since I can remember, helper classes have been the backbone of coding since they comprise all the utilities that are missing in the .Net framework.  The downside is that one must keep track of all the assemblies, namespaces and various implementations as the toolset grows.  This can be a daunting task when considering each client’s library and the exhaustive resources available in the developer community. Wouldn’t be nice if we could simply extend the functionality of our existing libraries?

.Net 3.5 now allows classes to be extended by using a specific type of method declaration.

//The key work 'this' is included at the beginning 
//of the parameter list with the type to be 
//extended.  You can then do any type of implementation you like 
public static void DoSomething(this string str) 
{   
}

The following attached example illustrates taking a simple helper class used for encrypting strings and converting it into an extension that becomes part of the .Net framework. 

ExtensionExample.zip (94.54 kb)



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5