C#で引数の省略はオーバーロードとは別である件

http://ufcpp.net/study/csharp/sp4_optional.html
C#で関数引数の省略は、「その関数を使う側」のビルド時に省略された引数を指定したことにしてビルドされることで実現されているみたいで、オーバーロードで引数省略を実現するのとは内部的には違うみたいである。
このせいで「ライブラリだけコンパイルしなおして再配布」しようとするとき悪影響が出る。
(VB.NETがどうなってるのかは確認してない)


引数の省略

class Class1()
{
	public string f1(string arg1="arg1") { return arg1; }
}

class Class2()
{
	public void main() { (new Class1()).f1(); }
}

これは内部的には、以下と等しい。

class Class1()
{
	public string f1(string arg1) { return arg1; }
}

class Class2()
{
	public void main() { (new Class1()).f1("arg1"); }
}

Class1とClass2が別のdllだとする。
このとき、Class1を「f1(string arg1="arg1")」→「f1(string arg1="arg1Ex")」と変更してビルドしても、Class2の動作はClass2をリビルドしない限り変わらない。(「f1("arg1")」が呼び出される)


オーバーロード

オーバーロードを使うと内部的にも以下のようなコードになる。

class Class1()
{
	public string f1()            { return f1("arg1"); }
	public string f1(string arg1) { return arg1; }
}

class Class2()
{
	public void main() { (new Class1()).f1(); }
}

これなら、Class1を「f1() { return f1("arg1"); }」→「f1() { return f1("arg1Ex"); }」と変更すれば、Class2の動作はリビルドしなくても変わる。



これって、なんで内部的にオーバーロード関数を作らないんだろう。
ていうか引数の省略がオーバーロードと別ものであるせいで、以下がエラー無しでビルド成功するのだが、どう考えてもおかしいだろ。

public class Class1
{
    public string f1()
    {
        return "no argument"; // 引数0個指定だと、こっちが呼ばれる
    }
    public string f1(string arg1 = "arg1")
    {
        return "one argument";
    }
}