Steve Wellens

Programming in the .Net environment

Sponsors

Links

July 2009 - Posts

Speed Up the Visual Studio Toolbox

There are plenty of tips out on the web that I see no need to repeat here. But this one made such a remarkable difference on my box that I had to post it….

I use the Auto-Hide property on the Toolbox to preserve screen real-estate. After adding the Ajax control toolkit to my environment, the Visual Studio Toolbox started to really drag. Instead of popping up quickly, the hard disk would churn for several seconds and the Toolbox would struggle, agonizingly and with apparently great reluctance, to appear.

When it did eventually appear, random sections of the Toolbox would be open. It didn't remember which tab was last used. Assuming the logic is in a background thread, I can only assume the thread was poorly written. If it was tested, the test results were ignored.

Thank goodness for the TooboxAutoPopulate setting.

Tools->Options->Windows Forms Designer->General

Setting AutoToolboxPopulate to False brought my machine back from the abyss of lost productivity caused by slow, clunky, energy-sapping GUI delays. Although the setting is under Windows Forms Designer, it is just as effective for ASP.Net developers (it's the same Toolbox).

I hope someone finds this helpful.

Steve Wellens

What’s the Deal with Interfaces?

This post is for beginners.

Many beginners struggle with the concept of an Interface. Over on the Asp.Net forums, where I moderate, the question is asked a surprising number of times. I'm going to try to describe and explain the concept of an Interface…simply and concisely.

Let's say we are going to program a game and the game needs a random number generator.

We want to try different random number generators because all random number generators are not created equal. To make it easy to switch number generators, we will use an Interface.

 

The Interface:

So, here is the (simple as possible) Interface for our Random Number Generator:

interface IRandomNumberGen
{
    int GetNextNumber();  
}

Notes:

The public keyword is not needed (or even allowed) on the GetNextNumber() method. An interface declares access methods so by default they must be public. A private method in an interface makes no sense...and causes an error.

An Interface cannot contain fields. Doing so causes an error.

Hmmm, it seems an Interface is a collection of empty functions that are implicitly public.

 

Derive some Classes from the Interface:

Here are two Random Number Generators each inheriting from our Interface.

class RandomNumberCoinFlip : IRandomNumberGen
{
    public int GetNextNumber()
    {
        // flip a coin for each bit of the number
        return 1;
    }
    private String CoinType; // penny, nickel, dime, etc.
}
 
class RandomNumberOuija  : IRandomNumberGen
{
    public int GetNextNumber()
    {
        // Use a Ouija board to get a number
        return 2;
    }
}

Notes:

Both classes implement the GetNextNumber() function. One class has an additional field…but that's OK; it doesn't matter:

As long as a class implements the functions in the Interface, it can do anything else it pleases. But a class derived from an Interface must implement the functions in the Interface.

So big deal, what have we accomplished?

 

Here are the Classes in Use:

protected void Button1_Click(object sender, EventArgs e)
{
    IRandomNumberGen Generator;
 
    Generator = new RandomNumberCoinFlip();
    Response.Write(Generator.GetNextNumber() + "<br />");
 
    Generator = new RandomNumberOuija();
    Response.Write(Generator.GetNextNumber() + "<br />");
}

Notes:  

The Generator reference can be assigned to any object created from a class derived from the IRandomNumberGen Interface and it can call the GetNextNumber() method. It doesn't know or care about any part of the class except the methods it expects to be there.

 

Here’s another usage example:

public void MakeAMove(IRandomNumberGen NumberGenerator)
{
    int Number = NumberGenerator.GetNextNumber();
 
    // do something with Random Number
}
 
protected void Button1_Click(object sender, EventArgs e)
{
    MakeAMove(new RandomNumberCoinFlip());
    MakeAMove(new RandomNumberOuija());
}

Notes:

This shows a function that takes an Interface as a parameter.  Any object derived from the Interface can be passed to the function.

That's cool but the same thing could be accomplished with an abstract base class and virtual functions. So what's the deal with Interfaces?

 

Multiple-Inheritance is not Supported in .Net….Except for Interfaces!

Here is one more class that implements the Interface. In addition to IRandomNumberGen, it implements IDisposable.

class RandomNumberDeckOfCardsIRandomNumberGen, IDisposable
{
    public int GetNextNumber()
    {
        // Shuffle deck, pick a card
        return 3;
    }
    public void Dispose()
    {
        // free up deck 
    }
}

And here it is being used:

protected void Button1_Click(object sender, EventArgs e)
{
    IRandomNumberGen Generator; 
 
    Generator = new RandomNumberDeckOfCards();
    Response.Write(Generator.GetNextNumber() + "<br />");
 
    IDisposable Disposer = Generator as IDisposable;
    Disposer.Dispose();
}

Notes:

As before, an IRandomNumberGen reference can be assigned to the object and the GetNextNumber() method called.

In addition, an IDisposable reference can be assigned (with a cast) to the object since it implements IDisposable and the Dispose() method can be called.

In the above code, the two Interface references, Generator and Disposer, both point to the same object. They have different 'views' of the same object. And that, is the deal with interfaces.

 

Finale:

I know there are thousands of articles around explaining this concept which is odd because once understood, the concept is trivial. But sometimes one explanation "fits the brain" better than another explanation. I hope this explanation fits someone's brain.

 

Update:

Many have asked for clarification between abstract classes and interfaces.  In addition to "multiple inheritance" which abstract classes do not support, there is another key difference:  Interface classes may NOT contain fields.  If you need fields or properties in the base class, you cannot use interfaces.

Update 2:

Correction: An interface does support properties:

public interface MyInterface
{
    int LastResult { get; set; }
}
 
public class MyClass : MyInterface
{
    public int LastResult { get; set; }
}

 

Steve Wellens

Posted: Jul 17 2009, 07:15 PM by SGWellens | with 23 comment(s) |
Filed under: , ,
Serializing and Deserializing Objects…to and from…XML

Over on the Asp.Net forums I recently had the opportunity* to help a few lost souls by showing them how to serialize objects to XML and deserialize the XML back into objects. Since the question has come up more than once, I decided to BLOG it so I could refer similar questions in the future to this post.

*I use the word opportunity because by helping others I am forced to think hard about the technology and to think even harder about how to communicate the technology. It makes me better at what I do. All right then, enough after-school-special-feel-good-about-yourself-I'm-ok-you're-ok fluffy nonsense… on with the code:

Here is a simple class I'm going to work with. It has both properties and fields:

public class MyClass
{
    // old school property
    private int _Age;  
    public int Age  
    {
        get { return _Age; }
        set { _Age = value; }
    }
 
    // new school property
    public bool Citizen { get; set; }
 
    // there's nothing wrong with using fields
    public string Name;  
}

Here are the two functions to Serialize and Deserialize an object:

/// ---- SerializeAnObject -----------------------------
/// <summary>
/// Serializes an object to an XML string
/// </summary>
/// <param name="AnObject">The Object to serialize</param>
/// <returns>XML string</returns>
 
public static string SerializeAnObject(object AnObject)
{
    XmlSerializer Xml_Serializer = new XmlSerializer(AnObject.GetType());
    StringWriter Writer = new StringWriter();      
 
    Xml_Serializer.Serialize(Writer, AnObject);
    return Writer.ToString();
}
 
 
/// ---- DeSerializeAnObject ------------------------------
/// <summary>
/// DeSerialize an object
/// </summary>
/// <param name="XmlOfAnObject">The XML string</param>
/// <param name="ObjectType">The type of object</param>
/// <returns>A deserialized object...must be cast to correct type</returns>
 
public static Object DeSerializeAnObject(string XmlOfAnObject, Type ObjectType)
{       
    StringReader StrReader = new StringReader(XmlOfAnObject);
    XmlSerializer Xml_Serializer = new XmlSerializer(ObjectType);
    XmlTextReader XmlReader = new XmlTextReader(StrReader);
    try
    {
        Object AnObject = Xml_Serializer.Deserialize(XmlReader);
        return AnObject;
    }
    finally
    {
        XmlReader.Close();
        StrReader.Close();
    }
}

Here is some sample code showing how to use the functions.

Note: I keep these functions (and other functions) in a class I call MiscUtilities. You will have to modify the code…depending on where you place the functions.

protected void Button1_Click(object sender, EventArgs e)
{
    // create and initialize an object
    MyClass Test = new MyClass();
 
    Test.Age = 18;
    Test.Name = "Rocky Balboa";
    Test.Citizen = true;
 
    //  Serialize it
    String XML;
 
    XML = MiscUtilities.SerializeAnObject(Test);
 
    // Deserialize it
    MyClass Test2;
 
    Test2 = MiscUtilities.DeSerializeAnObject(XML, typeof(MyClass)) as MyClass;
 
    // TODO:  Get a cup of coffee and bask in the glory of rock solid code.
}

Here is what the XML string looks like (after formatting):

<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Rocky Balboa</Name>
  <Age>18</Age>
  <Citizen>true</Citizen>
</MyClass>

There are limitations: XmlSerializer does not serialize private fields, methods, indexers or read-only fields.

Once you have the XML string, you can email it, store it in a database, save it to disk, or…print a copy of it and have your mom tape it to the refrigerator next to the picture of a turkey you made in second grade by tracing around your hand with a Crayola crayon.

I hope someone finds this useful.

More Posts