パスまたはファイル名の拡張子を別の拡張子に置き換えるにはChangeExtensionメソッドを使います。 元のパス・ファイル名に拡張子がない場合は拡張子が追加され、ピリオドが二つ以上あるファイル名の場合は一番最後のピリオド以降が置き換えられます。

ファイル名部分のうち、どの部分を拡張子と判断するかの基準はGetExtensionメソッドと同様です。 このため、UNIX系OSで隠しファイルとして扱われるドットファイル(dot file)では、ピリオドが一つだけ含まれる場合はファイル名全体が拡張子と判断され、ファイル名に対する置換が行われることになります。 この他、拡張子に関する注意点についてはGetExtensionメソッドを参照してください。

Path.ChangeExtensionメソッドで拡張子を別の拡張子に置換する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    foreach (var path in new[] {
      @"E:\dir\subdir\file.txt",  // 絶対パス (Windows形式)
      @"/dir/subdir/file.txt",    // 絶対パス (UNIX形式)
      @".\dir\subdir\file.txt",   // 相対パス (Windows形式)
      @"./dir/subdir/file.txt",   // 相対パス (UNIX形式)
      @"file.txt",                // ファイル名のみのパス
      @"file",                    // 拡張子のないファイル名
      @"file.txt.bak",            // ピリオドを二つ以上含むファイル名
      @"file.",                   // ピリオドで終わるファイル名
      @".file",                   // ピリオドで始まるファイル名
    }) {
      Console.WriteLine("path = {0}", path);
      Console.WriteLine("    => {0}", Path.ChangeExtension(path, ".dat")); // パスのファイル名の拡張子を.datに変更する
      Console.WriteLine();
    }

    // 変更後の拡張子はピリオドから始まっていても、いなくてもよい
    Console.WriteLine(Path.ChangeExtension("file.txt", "dat"));
    Console.WriteLine(Path.ChangeExtension("file.txt", ".dat"));

    // 変更後の拡張子は複数のピリオドを含んでいてもよい
    Console.WriteLine(Path.ChangeExtension("file.txt", "dat.bin"));
    Console.WriteLine(Path.ChangeExtension("file.txt", ".dat.bin"));
  }
}
実行結果
path = E:\dir\subdir\file.txt
    => E:\dir\subdir\file.dat

path = /dir/subdir/file.txt
    => /dir/subdir/file.dat

path = .\dir\subdir\file.txt
    => .\dir\subdir\file.dat

path = ./dir/subdir/file.txt
    => ./dir/subdir/file.dat

path = file.txt
    => file.dat

path = file
    => file.dat

path = file.txt.bak
    => file.txt.dat

path = file.
    => file.dat

path = .file
    => .dat

file.dat
file.dat
file.dat.bin
file.dat.bin
実行結果
path = E:\dir\subdir\file.txt
    => E:\dir\subdir\file.dat

path = /dir/subdir/file.txt
    => /dir/subdir/file.dat

path = .\dir\subdir\file.txt
    => .\dir\subdir\file.dat

path = ./dir/subdir/file.txt
    => ./dir/subdir/file.dat

path = file.txt
    => file.dat

path = file
    => file.dat

path = file.txt.bak
    => file.txt.dat

path = file.
    => file.dat

path = .file
    => .dat

file.dat
file.dat
file.dat.bin
file.dat.bin

置き換える拡張子に空の文字列(String.Empty)を指定した場合、ピリオドだけの拡張子に置換されます。 一方、null/Nothingを指定した場合は、ピリオドも含めて拡張子が削除されます。

特に、ピリオドが一つだけ含まれるドットファイルの場合、ピリオドだけのファイル名.、あるいは長さ0のファイル名に変換されることになるため、注意が必要です。