Practical Programming Pearls For .NET Developers

 (How)
C^# You Are - 14 September 2008

  1. How can you do a case insensitive string replacement in .NET?  Answer

    The standard String.Replace method is the primary choice for replacments but it is case sensitive.  The alternative choices are either String.IndexOf or Regex.Replace.  Both of these method can do case insensitive replacment.   Regex.Replace is the easiest.

    Regex re = new Regex("<input>", RegexOptions.IgnoreCase);
    str = re.Replace(str, "<replacement>");

    The alternative approach is to use String.IndexOf to find all occurrences and replace each one.

    int index = str.IndexOf("<input>");
    while (index >= 0)
    {
       str = str.Remove(index, "<input>".Length);
       str = str.Insert(index, "<replacement>");
      
       index = str.IndexOf("<input>", index + 1, StringComparison.CurrentCultureIgnoreCase);
    };

  2. How can you run a .NET application without installing the .NET framework?  Answer

    I see this question so many times on the forums I'm ready to scream.  Once and for all: YOU CANNOT USE .NET WITHOUT IT BEING INSTALLED!!!!

    It is the way it is.  I can't understand why people feel .NET is the best way to go to build and app but then feel that the overhead of installing the framework is too much.  If you don't want to install the framework then don't use .NET.  End of story.  However be aware that even C++ applications still require an installable component (aka RTL).  Fortunately .NET has been around long enough that most people have it either by installing another product or via Windows Update.  If you don't want to bloat your installer with .NET (a good choice for all but CD installs) then in your setup project tell the installer to link to the web version rather than embedding the installer.  It means that the end user has to be connected to download the framework but it won't bloat your installer.

    Just to be complete I'll point out that there is a product available that says it can add .NET to your app without requiring the framework but you should read the fine print.  The program works by embedding the framework into your binary.  This means that your program will be bigger (important if you were concerned about bloating the installer).  Even more important though is that your application will use the version of the framework that you compiled against rather than the version on the user's machine.  Service packs and security fixes will therefore require that you redeploy the application.  I wouldn't consider this an ideal solution for most apps.

  3. How do you create an extension method?  Answer

    Extension methods are identical to regular static methods (in fact they're implemented this way) with one exception.  An extension method marks the first parameter with the this keyword.  The first parameter identifies the type that will be extended.  Here is an example of a simple string helper method.

    public class static StringHelper
    {
       public static string LeftOf ( this string value, char delimiter, int startIndex )
       { ... }
    }

    Note that it is not important that the owning class be static but the method must be.

  4. The following code fails.  Why?  Answer

    using (StreamWriter writer = File.CreateText(fileName))
    {
       writer.WriteLine("Hello");
    };

    File.SetAttributes(fileName, FileAttributes.Hidden);

    //Fails here!!
    using (StreamWriter writer = new StreamWriter(fileName))
    { ... };

    This issue was reported in the forums recently (here).  The problem is with hidden files.  Under the hood the Win32 CreateFile function is used to create or open files.  The function is documented as failing if the CREATE_ALWAYS flag is used to always create the file (overwriting as needed), the file already exists but is hidden and the file being created does not have the hidden attribute set.  This is likely an issue with the underlying implementation.

    Internally StreamReader, and most of the other .NET classes, will use CreateFile to open the underlying file.  For StreamReader it will use either CREATE_ALWAYS or OPEN_ALWAYS depending upon whether the append parameter is used or not.  Because of this the class will fail on hidden files unless appending is enabled.  In the above example including the append parameter will resolve the issue.