String.ToUpperメソッドは文字列を大文字化するメソッド、String.ToLowerメソッドは文字列を小文字化するメソッドです。

ToUpperメソッドとToLowerメソッドは現在のスレッドの(もしくは引数で指定された)カルチャの規則に基づいて大文字化・小文字化しますが、String.ToUpperInvariantメソッドString.ToLowerInvariantメソッドインバリアントカルチャ(特定の文化圏や言語に依存しない)の規則に基づいて大文字化・小文字化します。

ToUpper/ToUpperInvariantToLower/ToLowerInvariantの違いは、大文字化・小文字化の際に参照される規則です。

例えば、トルコ語においては i の大文字は I(U+0049) ではなく İ(U+0131) で、I の小文字は i(U+0069) ではなく ı(U+0130) となるため、スレッドのカルチャがトルコ語の場合ToUpper/ToLowerの結果はToUpperInvariant/ToLowerInvariantと異なる結果となります。

String.ToUpper/ToUpperInvariantとToLower/ToLowerInvariantメソッドで異なる結果となる例
using System;
using System.Globalization;
using System.Threading;

class Sample {
  static void Main()
  {
    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
    Console.WriteLine("i: {0} {1}", "i".ToUpperInvariant(), "i".ToUpper());
    Console.WriteLine("I: {0} {1}", "I".ToLowerInvariant(), "I".ToLower());

    // 現在のスレッドのカルチャをtr-TR(トルコ語/トルコ)に変更
    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR");

    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
    Console.WriteLine("i: {0} {1}", "i".ToUpperInvariant(), "i".ToUpper());
    Console.WriteLine("I: {0} {1}", "I".ToLowerInvariant(), "I".ToLower());
  }
}
実行結果
ja-JP
i: I I
I: i i
tr-TR
i: I İ
I: i ı

したがって、カルチャや変換規則を強く意識する必要がある場合はToUpper/ToLowerを用いる必要があります。 一方それ以外の多くの場合はToUpperInvariant/ToLowerInvariantで十分と言えます。 特に、単にASCIIの範囲の文字だけを大文字/小文字にしたいという目的であれば、カルチャと変換規則に影響されないToUpperInvariant/ToLowerInvariantのほうが適切かつパフォーマンス的にも優れると考えられます。

カルチャと変換規則についてはStringComparisonとStringComparerでも詳しく説明しています。