DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 3.3 Converting a String Representation of an Object into an Actual Object

Problem

You need a way of accepting a string containing a textual representation of an object and converting it to an object usable by your application. For example, if you were provided with the string representation of a line (x1, y1)(x2, y2), you would want to convert it into a Line structure.

Solution

Implement a Parse method on your Line structure:

using System;
using System.Text;
using System.Text.RegularExpressions;

public struct Line
{
    public Line(int startX, int startY, int endX, int endY)
    {
        x1 = startX;
        x2 = endX;
        y1 = startY;
        y2 = endY;
    }

    public int x1;
    public int y1;
    public int x2;
    public int y2;

    public static Line Parse(string stringLine)
    {
        if (stringLine == null)
        {
            throw (new ArgumentNullException("stringLine", 
                       "A null cannot be passed into the Parse method."));
        }

        // Take this string (x1,y1)(x2,y2) and convert it to a Line object
        int X1 = 0;
        int Y1 = 0;
        int X2 = 0;
        int Y2 = 0;

        MatchCollection MC = Regex.Matches(stringLine, 
                @"\s*\(\s*(?<x1>\d+)\s*\,\s*(?<y1>\d+)\s*\)\s*
                     \(\s*(?<x2>\d+)\s*\,\s*(?<y2>\d+)\s*\)" );

        if (MC.Count == 1)
        {
            Match M = MC[0];
            X1 = int.Parse(M.Groups["x1"].Value);
            Y1 = int.Parse(M.Groups["y1"].Value);
            X2 = int.Parse(M.Groups["x2"].Value);
            Y2 = int.Parse(M.Groups["y2"].Value);
        }
        else
        {
            throw (new ArgumentException(
              "The value " + stringLine + " is not a well formed Line value."));
        }

        return (new Line(X1, Y1, X2, Y2));
    }
}

Discussion

The Parse method is used to reconstruct one data type—in this case, a String—into the data type containing that Parse method. For example, if the string "123" were passed into the int.Parse method, the numeric data type 123 would be extracted and then returned. Many other types in the FCL use a Parse method to reconstruct an object of its own type from another data type, such as a string. Note that you are not limited as far as the type and number of parameters that can be passed into this method. As an example, see how the DateTime.Parse and DateTime.ParseExact methods are defined and overloaded.

The parsing of a string containing the start and end coordinates of a line is a little more difficult. To make things easier, we use a regular expression to extract the beginning and ending X and Y coordinates.

The regular expression parses out the individual coordinate values provided by the stringLine string parameter. Each found coordinate is passed on to the static int.Parse method on the int structure. This final step obtains the final parsed integer values from the matches produced by the regular expression. If the regular expression does not extract the required coordinates, we can assume that the stringLine parameter does not contain a well-formed string that can be converted to a Line object.

The following code:

Console.WriteLine("Line.Parse(\"(12,2)(0,45)\") = " + Line.Parse("(12,2)(0,45)"));
Console.WriteLine("Line.Parse(\"(0,0)(0,0)\") = " + Line.Parse("(0,0)(0,0)"));

produces this output:

Line.Parse("(12,2)(0,45)") = (12,2) (0,45)
Line.Parse("(0,0)(0,0)") = (0,0) (0,0)

When implementing a Parse method on your own types, you need to consider the situation where invalid data is passed to this method. When this happens, an ArgumentException should be thrown. When a null is passed in, you should instead throw an ArgumentNullException.


See Also

See the "Parse Method" topic; see the Parse Sample under the ".NET Samples—How To: Base Data Types" topic in the MSDN documentation.

    [ Team LiB ] Previous Section Next Section