May 2007 - Posts

.NET: Passing a DataSet through the ExtendedProperties of another DataSet

 Sometimes you find the need to pass more than one DataSet as the result of a routine/function.  Although you can use reference parameters for doing so, there's another approach.

You can pass additional DataSets by adding them to the ExtendedProperties property of the "main" DataSet.  ExtendedProperties is defined as being of type PropertyCollection, which inherits from the Hashtable type, so its limit depends on the amount of memory that the host machine has.

A limitation that becomes apparent when using .NET remoting is that the values stored in the ExtendedProperties should be of type string in order to be persistent when it crosses the application domains between the server and the client.  With this limitation in mind, the steps are roughly as follows:

1.   Convert the "additional" DataSet to string.
2.   Store the result of step 1 in the ExtendedProperties of the "main" DataSet.
3.   Pass/return the "main" DataSet to the calling process.
4.   Convert the string representation of the "additional" DataSet back.

Essential routines/information:
Step 1:
The DataSet class has a GetXml method that returns the XML representation of the DataSet.

Steps 2 & 3:
Self explanatory.

Step 4:
The DataSet class has a ReadXml method for initalizing a DataSet based on XML.

Combining all the information, the code can look something like this:
==== START OF SAMPLE CODE ====
// SAMPLE FUNCTION (SampleFunction())
....
using System.Data;
....
DataSet dsMain;
DataSet dsSub;
....
// Populate the DataSets here
...
string dsSubAsString;
dsSubAsString = dsSub.GetXml();
dsMain.ExtendedProperties.Add("dsSub", dsSubAsString);
...
// Pass dsMain to calling routine/function


// CALLING FUNCTION
...
using System.Data;
using System.IO;
...
DataSet dsMainReturn;
DataSet dsSubReturn;

// Call function to retrieve the DataSets
// and convert dsSub
...
dsMainReturn = SampleFunction();
dsSubReturn = new DataSet();

string dsSubReturnAsString = (string) dsMainReturn.ExtendedProperties["dsSub"];

using (System.IO.StringReader sr = new StringReader(dsSubReturnAsString))
{
    dsSubReturn.ReadXml(sr, XmlReadMode.InferSchema);
}

...
// Use dsSubReturn as required
...
==== END OF SAMPLE CODE ====


And there you have it.  Taking it a step further, the code for conversion from XML/string to DataSet can be wrapped as a function in a helper class, so as not to affect programmer productivity. :)

Posted by raistlin | with no comments
Filed under: , ,

.NET: How to determine if a string comes before another string based on the dictionary order

 Language: C#

Usually string comparisons are needed just to determine the equality (or inequality) of 2 strings.  However, there are times when determining inequality isn't the end in itself.  Sometimes a developer also needs to know if a particular string should "come before" another string --  alphabetically , based on the common dictionary order.

The regular relational operators ( <, >, =<. >=) do not work on string variables and/or literals. So using:

    if (string1 < string2)
    {
       //    code here
    }


is out of the question because the compiler will not even allow it.  So what's the alternative?  As it turns out, the same function that I mentioned for performing case-insensitive string operations (string.Compare), is also capable of determining if the first string parameter alphabetically comes before the second string parameter.  The function returns zero (== 0) if the strings are equal, a negative value (< 0) if the first string is "less than" (alphabetically comes before) the second string, and a positive value (> 0) if the first string is "greater than" (alphabetically comes after) the second string.  Given this, the following code will return a negative value:

    string.Compare("B21", "B22");

whereas this will return a positive value:

    string.Compare("B22", "B21");

Now, if the strings are not of equal length, the longer string is always considered "greater" than the shorter string.  So the following code will return a negative value:

    string.Compare("B2", "B21");

And, of course, you can perform case-insensitive comparisons, e.g.

    string.Compare("b22", "B21", false);

As always, please refer to the MSDN documentation for additional information. Link

Posted by raistlin | with no comments
Filed under: , ,

.NET: Performing case-insensitive string comparison

 Language: C#

Performing string comparisons can be considered as one of the "common" tasks that a programmer needs to do and, more often than not, the comparisons need to be case-insensitive.  The common method taught (or learned, as the case may be) is to convert the entire string to upper case or lower case and perform the comparison accordingly against the appropriate literal.  There's nothing wrong with that method and it has been used since time immemorial.

However, in the .NET environment strings are immutable, and calling the ToLower()/ToUpper() methods of the string class internally creates a new string variable.  A new variable means additional overhead in terms of processor time (the duration consumed during the allocation, creation and assignment of the new variable) and the actual memory consumption of the new variable.  It may not be enough to affect performance, but when you need to squeeze every last bit of available memory for an application, this can become crucial.

So what's the alternative?  Incidentally, the string class provides a static method for performing case-insensitive comparisons without the additional overhead.  It's the Compare method.  It has six overloads but, for the purpose of this mail, i'll just mention one.  The overload we're interested in has the following signature:

    public static int Compare( string strA, string strB, bool ignoreCase)

Equality is indicated by a return value of 0 (zero).  Given this, instead of:

    if (someString.ToUpper() == "VALUE")
    ...
we can use this:

    if (string.Compare(someString, "VALUE", true) == 0)
    ...

or:
    if (string.Compare(someString, "value", true) == 0)
    ...

or:
    if (string.Compare(someString, "vAlUe", true) == 0)
    ...

etc.


As you can see, it's also less prone to mistakes.  As against to calling ToUpper() and comparing a string to a literal which is composed of lowercase characters by accident.

Other overloads for the Compare method enable developers to specify culture information, compare the substrings of 2 strings, etc.
Please refer to the MSDN documentation for additional information. Link

Posted by raistlin | 3 comment(s)
Filed under: , ,