Practical Programming Pearls For .NET Developers

 (How)
C^# You Are - 31 October 2008

  1. Your application uses multiple configuration files (MyApp#.xml) to support multiple "instances" of your application.  Each instance is represented by a number between 1 and 64 (passed via the command line).  The default instance uses the MyApp.xml file.  You need to write some code to retrieve the configured instance numbers to display to the user.  How can you do that?  Answer

    On the surface this might not sound too bad.  Given that instances are between 1 and 64, plus the default, the possible combinations are finite.  If you assume that instances are not necessarily sequential then things can get a little more complicated.

    The most obvious solution is the brute force method of attempting to open all files between 1 and 64, plus the default.  While this would work it will be really slow.  Even worse is that if you use any method that might throw an exception when the file is not found then you can end up with a lot of exceptions.  For files there are ways to check for the existence of a file but other mediums (like the registry) might not provide such an option.

    The best approach is to query for all files that match the desired file mask.  You can then enumerate the filenames looking for matches.

    string mask = "MyApp*.xml";
    string[] files = Directory.GetFiles(path, mask);
    
    Regex re = new Regex(@"MyApp(?<Instance>\d*).xml$");
    foreach (string file in files)
    {
       Match m = re.Match(Path.GetFileName(file));
       if (m.Success)
       {                    
          Console.WriteLine(m.Groups["Instance"].Value);
       };
    };

    Here I used a regular expression to pull out the instance name.  When dealing with string searches of patterns it is often faster and cleaner to use a regular expression.  In this case I used a named capture group to grab just the instance name from the file name.  I also appended a $ to the end so I would only match the whole filename rather than part of it.

  2. You have created a custom configuration section for your application's settings.  Within your custom section you have added a child configuration element that must be specified.  You define the property but the subsystem never generates an error when the element is excluded.  What is wrong with your code?  Answer
    class MyConfigurationSection : ConfigurationSection
    {
       ...
    
       [ConfigurationProperty("child", IsRequired=true)]
       public MyChildElement Child
       { get { return this["child"]; } }
    }

    There is no problem with your code.  The problem lies in how the subsystem is implemented.  The IsRequired property does not work properly when applied to a ConfigurationElement via the ConfigurationPropertyAttribute.  The subsystem relies on the existence (or lack thereof) to determine if a required property is specified in the configuration file or not.  For child elements a value is always created.  Hence the subsystem cannot determine if the property was specified or not.

    The best workaround is to programmatically declare the property rather than using the attribute.  While this is more work it will resolve the issue.

  3. Write a function to convert an unsigned integer to a boolean string?  Answer

    Converting from decimal to binary is a textbook operation. Keep dividing the number by 2 and save off the remainder. Once you have divided all the bits then return the string in the opposite order.

    static string ToBinary ( uint value )
     {
        StringBuilder bldr = new StringBuilder(32);
        for (int pos = 0; pos < 32; ++pos)
        {
           if ((pos % 4) == 0)
              bldr.Insert(0, ' ');
     
           bldr.Insert(0, (value % 2) == 1 ? '1' : '0');
           value /= 2;
        };
     
        return bldr.ToString();
     }


  4. What happens if you overflow an integral value during a calculation. For example this code: int value = Int32.MaxValue; ++value;?  Answer

    The default behavior is to ignore the overflow and simply wrap the number around. This is the most efficient mechanism as the runtime doesn't need to check anything.  However if overflow is important to you then you can wrap the operation in a checked block to have an exception thrown if overflow occurs. If you are interested in having all integral arithmetic operations checked then you can specify the /checked compiler option to default the behavior instead.

     checked
     {
        int value = Int32.MaxValue;
        ++value;
     };


  5. What does the unsafe keyword do in C#?  Answer

    This rarely used keyword can be used to temporarily remove some of the memory restrictions in C#.  Specifically it allows C# to use pointers. When used in a function declaration it allows you to use pointers in the function signature.  When used as a block statement it allows you to work with pointers within a block of code. 

    In my experience there is never a case where this keyword should be used.  Even when working with native code and memory buffers it is possible to stick with the managed functionality exposed for interop rather than using the unsafe keyword.  The code might be a little more complex and might not be as efficient but it is definitely safer.  Still there might be times where unsafe code might just make the code a little easier to use, perhaps during a migration.  To use this keyword you have to also add the /unsafe options to the compiler.

    Here is an example:

     byte[] buffer = { 10, 20, 30, 40 };
     unsafe 
     {
        byte* ptr = buffer;
       ... 
     };


  6. What does the explicit keyword do in C#?  Answer

    This keyword can be applied to type conversion operators of a class.  Normally when you define a type conversion operator the compiler will implicitly use the operator, when needed, to convert from type A to type B.  In a few cases the conversion might be important/expensive enough that you do not want the compiler to use the operator implicitly.  Applying the explicit keyword prevents the compiler from using the operator unless you explicitly cast the value first.  In the following example we have defined a Letter class that holds only letters.  It makes sense to allow conversion to and from characters.  Therefore we define a type conversion operator like so.

    class Letter
     {
        public Letter ( char value )
        {
           Value = value;
        }
     
        public static implicit operator Letter(char value)
        {
           return new Letter(value);
        }
     
        public char Value 
        {
            get { return m_Value; }
     
            set
            {
                if (!Char.IsLetter(value))
                    throw new ArgumentException("Not a letter.", "value");
     
                m_Value = value;
            }
        }
     
        private char m_Value;
     }
     
    //Usage
     static void Main ( )
     {
        Letter letter = new Letter('B');
        letter = 'a';

    However it can be confusing when an implicit type conversion is used and it throws an exception (as it would here if the character was not a letter). Therefore it is often better to make the conversion explicit, but allowable, via the explicit keyword like so.  Now the user must put an explicit typecast in their code but if something goes wrong it is far more obvious what the problem might be.

    public static explicit operator Letter(char value)
     {
        return new Letter(value);
     }
     
    //Usage
     static void Main ( )
     {
        Letter letter = new Letter('B');
        letter = (Letter)'a';
     }