<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dutton Software &#187; C#</title>
	<atom:link href="http://www.duttonsoftware.com/category/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.duttonsoftware.com</link>
	<description>Code, plug-ins &#38; more</description>
	<lastBuildDate>Fri, 05 Mar 2010 17:19:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>String extensions &#8211; Case-insensitive Replace and Contains</title>
		<link>http://www.duttonsoftware.com/2008/12/07/string-extensions-case-insensitive-replace-and-contains/</link>
		<comments>http://www.duttonsoftware.com/2008/12/07/string-extensions-case-insensitive-replace-and-contains/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 04:52:44 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[Contains]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Replace]]></category>

		<guid isPermaLink="false">http://www.duttonsoftware.com/?p=125</guid>
		<description><![CDATA[The C# string library is pretty comprehensive, but there are a few methods that were left out. Luckily, in C# 3.0 extensions were introduced, which allows developers to seemingly add methods to existing classes. Remember that extensions only work inside the same namespace, so you&#8217;ll have to rename &#8220;MyNamespace&#8221; in the example below. Two of [...]]]></description>
			<content:encoded><![CDATA[<p>The C# string library is pretty comprehensive, but there are a few methods that were left out.  Luckily, in C# 3.0 extensions were introduced, which allows developers to seemingly add methods to existing classes.  Remember that extensions only work inside the same namespace, so you&#8217;ll have to rename &#8220;MyNamespace&#8221; in the example below.</p>
<p>Two of the missing methods are case-insensitive versions of the methods &#8220;Contains&#8221; and &#8220;Replace&#8221;.  I do not take credit for writing the methods &#8212; I found them on Google and have provided references in the code.  I did add the comments to make the overloaded methods match the originals.  I also tested them to make sure they behaved like the originals when provided with a null or empty string.</p>
<p>I&#8217;m not sure why the .NET team did not provide case-insensitive Replace or case-insensitive Contains, they do it with many other string methods like StartsWith and EndsWith.  Hopefully these help.</p>
<p>The case-insensitive Contains code is heavily based on <a href="http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/566ed130-361d-44d0-b6dc-cbcd19d57627/" target="_new">a post on this forum</a>.  The case-insensitive Replace code is heavily based on <a href="http://www.codeproject.com/script/Forums/View.aspx?fid=195463&amp;msg=2514269" target="_new">a Code Project comment</a>.  Learn more about <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_new">C# extensions on MSDN</a>.</p>
<p>Please note that I had to butcher some of the XML comments because the code formatter was deleting them.  It shouldn&#8217;t affect compiling, but you may have to fix some if you want the full Intellisense.</p>
<pre class="brush: csharp;">
using System;
using System.Text;

namespace MyNamespace
{
    /// &lt;summary&gt;
    /// Overloads the string object and adds case-insenstive options to certain methods
    /// &lt;/summary&gt;
    public static class StringExtensions
    {
        /// &lt;summary&gt;
        /// Returns a value indicating whether the specified System.String object occurs
        /// within this string.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;original&quot;&gt;The System.String object to be checked.&lt;/param&gt;
        /// &lt;param name=&quot;value&quot;&gt;The System.String object to seek.&lt;/param&gt;
        /// &lt;param name=&quot;comparisonType&quot;&gt;One of the System.StringComparison values that
        /// determines how this string and value are compared.&lt;/param&gt;
        /// &lt;returns&gt;true if the value parameter occurs within this string, or
        /// if value is the empty string (&quot;&quot;); otherwise, false.&lt;/returns&gt;
        /// &lt;exception cref=&quot;System.ArgumentNullException&quot;&gt;value is null.&lt;/exception&gt;
        static public bool Contains(this string original, string value, StringComparison comparisonType)
        {
            if (original == null)
                throw new NullReferenceException(&quot;Object reference not set to an instance of an object.&quot;);

            if (value == null)
                throw new ArgumentNullException(&quot;value&quot;);

            if (String.Empty == value)
                return true;

            return (0 &lt; = original.IndexOf(value, comparisonType));
        }

        /// &lt;summary&gt;
        /// Replaces all occurrences of a specified System.String in this instance
        /// with another specified System.String. &lt; / summary&gt;
        /// &lt;param name=&quot;original&quot;&gt;The System.String object to be searched.&lt;/param&gt;
        /// &lt;param name=&quot;oldValue&quot;&gt;A System.String to be replaced.&lt;/param&gt;
        /// &lt;param name=&quot;newValue&quot;&gt;A System.String to replace all occurrences of oldValue.&lt;/param&gt;
        /// &lt;param name=&quot;comparisonType&quot;&gt;One of the System.StringComparison values that
        /// determines how this string and value are compared.&lt;/param&gt;
        /// &lt;returns&gt;A System.String equivalent to this instance but with all
        /// instances of oldValue replaced with newValue.&lt;/returns&gt;
        /// &lt;exception cref=&quot;System.ArgumentNullException&quot;&gt;oldValue is null.&lt;/exception&gt;
        /// &lt;exception cref=&quot;System.ArgumentException&quot;&gt;oldValue is the empty string (&quot;&quot;).&lt;/exception&gt;
        static public string Replace(this string original, string oldValue, string newValue, StringComparison comparisonType)
        {
            if (original == null)
                throw new NullReferenceException(&quot;Object reference not set to an instance of an object.&quot;);

            if (oldValue == null)
                throw new ArgumentNullException(&quot;oldValue&quot;);

            if (String.Empty == oldValue)
                throw new ArgumentException(&quot;oldValue&quot;);

            int lenPattern = oldValue.Length;
            int idxPattern = -1;
            int idxLast = 0;

            StringBuilder result = new StringBuilder(original.Length);

            while (true)
            {
                idxPattern = original.IndexOf(oldValue, idxPattern + 1, comparisonType);

                if (idxPattern &lt; 0)
                {
                    result.Append(original, idxLast, original.Length - idxLast);
                    break;
                }

                result.Append(original, idxLast, idxPattern - idxLast);
                result.Append(newValue);

                idxLast = idxPattern + lenPattern;
            }

            return result.ToString();
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.duttonsoftware.com/2008/12/07/string-extensions-case-insensitive-replace-and-contains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
