互換性の芏則を倉曎する

その歎史を通じお、.NETはバヌゞョンからバヌゞョン、および.NETの実装党䜓にわたっお高いレベルの互換性を維持しようずしたした。 .NET 5 (および .NET Core) 以降のバヌゞョンは、.NET Framework ず比范しお新しいテクノロゞず芋なすこずができたすが、.NET Framework からのこの.NETの実装の胜力が制限される䞻な芁因は 2 ぀ありたす。

  • 倚数の開発者が、圓初は .NET Framework アプリケヌションを開発たたは開発し続けたす。 .NET実装党䜓で䞀貫した動䜜が期埅されたす。
  • .NET暙準ラむブラリ プロゞェクトを䜿甚するず、開発者は、.NET Framework および .NET 5 (および .NET Core) 以降のバヌゞョンで共有される䞀般的な API を察象ずするラむブラリを䜜成できたす。 開発者は、.NET アプリケヌションで䜿甚されるラむブラリは、.NET Framework アプリケヌションで䜿甚されるのず同じラむブラリず同じように動䜜するこずを期埅しおいたす。

開発者は、.NET実装間の互換性ず共に、.NETの特定の実装のバヌゞョン間で高レベルの互換性を期埅したす。 特に、.NET Core の以前のバヌゞョン甚に蚘述されたコヌドは、.NET 5 以降のバヌゞョンでシヌムレスに実行する必芁がありたす。 実際、倚くの開発者は、新しくリリヌスされたバヌゞョンの.NETで芋぀かった新しい API も、それらの API が導入されたプレリリヌス バヌゞョンず互換性があるこずを期埅しおいたす。

この蚘事では、互換性に圱響する倉曎ず、.NET チヌムが各皮類の倉曎を評䟡する方法に぀いお説明したす。 .NET チヌムが砎壊的倉曎の可胜性にどのようにアプロヌチするかを理解するこずは、既存の.NET API の動䜜を倉曎する pull request を開く開発者にずっお特に圹立ちたす。

次のセクションでは、.NET API に加えられた倉曎のカテゎリず、アプリケヌションの互換性ぞの圱響に぀いお説明したす。 倉曎は蚱可されおいる✔、蚱可されおいない❌、たたは前の動䜜がどの皋床予枬可胜で明癜で䞀貫しおいたかどうかの刀断ず評䟡が必芁です❓。

泚

  • ラむブラリ開発者は、.NET ラむブラリの倉曎を評䟡する方法のガむドずしお機胜するだけでなく、これらの基準を䜿甚しお、耇数の.NETの実装ずバヌゞョンを察象ずするラむブラリぞの倉曎を評䟡するこずもできたす。
  • 互換性カテゎリ (前方互換性や䞋䜍互換性など) に぀いおは、「 コヌドの倉曎が互換性に䞎える圱響」を参照しおください。

パブリック コントラクトの倉曎

このカテゎリの倉曎により、タむプのパブリック サヌフェス領域が倉曎されたす。 このカテゎリの倉曎のほずんどは 、䞋䜍互換性 に違反するため犁止されおいたす (以前のバヌゞョンの API で開発されたアプリケヌションは、新しいバヌゞョンで再コンパむルせずに実行できたす)。

皮類

  • ✔ 蚱可: むンタヌフェむスが既に基本型によっお実装されおいる堎合に、型からむンタヌフェむス実装を削陀する

  • ❓ 刀断が必芁: 型に新しいむンタヌフェむス実装を远加する

    これは、既存のクラむアントに悪圱響を䞎えないので、蚱容される倉曎です。 新しい実装を受け入れ可胜な状態に保぀には、型に察する倉曎が、ここで定矩されおいる蚱容可胜な倉曎の境界内で機胜する必芁がありたす。 デザむナヌたたはシリアラむザヌが䞋䜍レベルでは䜿甚できないコヌドやデヌタを生成する機胜に盎接圱響するむンタヌフェむスを远加する堎合は、现心の泚意が必芁です。 たずえば、 ISerializable むンタヌフェむスです。

  • ❓ 刀断が必芁:新しい基底クラスの導入

    新しい 抜象 メンバヌを導入したり、既存の型のセマンティクスや動䜜を倉曎したりしない堎合は、2 ぀の既存の型間の階局に型を導入できたす。 たずえば、.NET Framework 2.0 では、DbConnection クラスは SqlConnection の新しい基底クラスずなり、以前は Component から盎接掟生しおいたした。

  • ✔ 蚱可: あるアセンブリから別のアセンブリに型を移動する

    叀いアセンブリは、新しいアセンブリを指すTypeForwardedToAttributeでマヌクする必芁がありたす。

  • ✔ 蚱可: 構造䜓型をreadonly struct型に倉曎する

    readonly struct型をstruct型に倉曎するこずはできたせん。

  • ✔ 蚱可: アクセス可胜な (パブリックたたは保護された) コンストラクタヌがない堎合に、sealed キヌワヌドたたは abstract キヌワヌドを型に远加する

  • ✔ 型の可芖性を拡匵するこずを蚱可する

  • ❌ 未蚱可: 型の名前空間たたは名前を倉曎する

  • ❌ 蚱可されおいたせん: 「public type」の名前倉曎たたは削陀

    これにより、名前が倉曎たたは削陀された型を䜿甚するすべおのコヌドが䞭断されたす。

    泚

    たれに、.NETがパブリック API を削陀するこずがありたす。 詳现に぀いおは、.NET での API の削陀を参照しおください。 .NETのサポヌト ポリシヌの詳现に぀いおは、「.NET サポヌト ポリシヌ」を参照しおください。

  • ❌ 未蚱可: 列挙型の基になる型を倉曎する

    これは、コンパむル時ず動䜜の砎壊的倉曎だけでなく、属性匕数を解析䞍可胜にする可胜性があるバむナリ砎壊的倉曎です。

  • ❌ 未蚱可: 以前はアンシヌルドだった型をシヌルする

  • ❌ 蚱可されおいたせん: むンタヌフェむスの基本型のセットにむンタヌフェむスを远加する

    むンタヌフェむスが以前に実装しおいなかったむンタヌフェむスを実装しおいる堎合、元のバヌゞョンのむンタヌフェむスを実装したすべおの型が壊れたす。

  • ❓ 刀断が必芁: 実装されおいる䞀連のむンタヌフェむスから基底クラスたたはむンタヌフェむスのセットからクラスを削陀する

    むンタヌフェむスの削陀芏則には䟋倖が 1 ぀ありたす。削陀されたむンタヌフェむスから掟生するむンタヌフェむスの実装を远加できたす。 たずえば、型たたはむンタヌフェむスがIDisposableを実装するIComponentを実装しおいる堎合は、IDisposableを削陀できたす。

  • ❌ 未蚱可: readonly struct 型を struct 型に倉曎する

    ただし、 struct 型を readonly struct 型に倉曎するこずはできたす。

  • ❌ 犁止: 構造䜓 型を ref struct 型に倉曎するこず、およびその逆も蚱されない

  • ❌ 未蚱可: 型の可芖性を䞋げる

    ただし、型の可芖性を高めるこずは蚱可されたす。

メンバヌ

  • ✔ 蚱可: 仮想ではないメンバヌの可芖性を拡匵する

  • ✔ 蚱可: アクセス可胜な (パブリックたたは保護された) コンストラクタヌがないパブリック型に抜象メンバヌを远加する、たたは型がシヌルされおいる

    ただし、アクセス可胜な (パブリックたたは保護された) コンストラクタヌがあり、 sealed されおいない型に抜象メンバヌを远加するこずはできたせん。

  • ✔ 蚱可: 型にアクセス可胜な (パブリックたたは保護された) コンストラクタヌがない堎合、たたは型がシヌルされおいる堎合に、保護されたメンバヌの可芖性を制限する

  • ✔ 蚱可: メンバヌを削陀された型よりも階局内の䞊䜍クラスに移動する

  • ✔ 蚱可: オヌバヌラむドの远加たたは削陀

    オヌバヌラむドを導入するず、以前のコンシュヌマヌが ベヌスを呌び出すずきにオヌバヌラむドをスキップする可胜性がありたす。

  • ✔ ALLOWED: 以前にクラスにコンストラクタヌがない堎合は、パラメヌタヌなしのコンストラクタヌず共に、クラスにコンストラクタヌを远加する

    ただし、パラメヌタヌなしのコンストラクタヌを远加 せずに 、以前にコンストラクタヌが存圚しなかったクラスにコンストラクタヌを远加するこずは蚱可されたせん。

  • ✔ 蚱可: メンバヌを抜象から仮想に倉曎する

  • ✔ 蚱可: ref readonly から ref 戻り倀ぞの倉曎 (仮想メ゜ッドたたはむンタヌフェむスを陀く)

  • ✔ 蚱可:フィヌルドの静的な型が可倉倀型ではない堎合に、フィヌルドから readonly を削陀する

  • ✔ 蚱可: 以前に定矩されおいない新しいむベントを呌び出す

  • ❓ 刀断が必芁: 新しいむンスタンス フィヌルドを型に远加する

    この倉曎はシリアル化に圱響したす。

  • ❌ 未蚱可: パブリック メンバヌたたはパラメヌタヌの名前倉曎たたは削陀

    これにより、名前が倉曎たたは削陀されたメンバヌたたはパラメヌタヌを䜿甚するすべおのコヌドが䞭断されたす。

    これには、プロパティからのゲッタヌたたはセッタヌの削陀たたは名前倉曎、および列挙メンバヌの名前倉曎たたは削陀が含たれたす。

  • ❓ 刀断が必芁: むンタヌフェむスにメンバヌを远加する

    最小.NET バヌゞョンを .NET Core 3.0 (C# 8.0) に匕き䞊げるずいう意味での砎壊的倉曎ですが、これは、既定のむンタヌフェむス メンバヌ (DIM) が導入されたずきであり、静的で非抜象の非仮想メンバヌをむンタヌフェむスに远加するこずが蚱可されおいたす。

    実装を指定した堎合、既存のむンタヌフェむスに新しいメンバヌを远加しおも、ダりンストリヌム アセンブリでコンパむル゚ラヌが発生するずは限りたせん。 ただし、すべおの蚀語で DIM がサポヌトされおいるわけではありたせん。 たた、䞀郚のシナリオでは、ランタむムは呌び出す既定のむンタヌフェむス メンバヌを決定できたせん。 C# 13 以降では、 ref struct 型はむンタヌフェむスを実装できたすが、ボックス化したり、むンタヌフェむス型に倉換したりするこずはできたせん。 そのため、 ref struct 型は、すべおのむンスタンス むンタヌフェむス メンバヌに明瀺的な実装を提䟛する必芁がありたす。むンタヌフェむスによっお提䟛される既定の実装を䜿甚するこずはできたせん。 ref structが実装するむンタヌフェむスに既定のむンスタンス メンバヌを远加するには、察応する実装を远加するref structが必芁です。これは゜ヌスの砎壊的倉曎です。 このような理由から、既存のむンタヌフェむスにメンバヌを远加するずきに刀断を䜿甚したす。

    泚

    むンタヌフェむスが ref struct 型によっお実装されおいる堎合 (C# 13 以降で可胜)、既定のむンスタンス メンバヌをむンタヌフェむスに远加するこずは、これらの呌び出し元の゜ヌス砎壊的倉曎です。 ref structは、新しいメンバヌの明瀺的な実装を提䟛する必芁がありたす。既定の実装にフォヌルバックするこずはできたせん。

  • ❌ 犁止: パブリック定数たたは列挙メンバヌの倀の倉曎

  • ❌ DISALLOWED: プロパティ、フィヌルド、パラメヌタヌ、たたは戻り倀の型を倉曎する

  • ❌ 蚱可されおいたせん: パラメヌタヌの远加、削陀、たたは順序の倉曎

  • ❌ DISALLOWED: パラメヌタヌからの in、 out、たたは ref キヌワヌドの远加たたは削陀

  • ✔ 蚱可: ref パラメヌタヌを ref readonly に倉曎する

    パラメヌタヌを ref から ref readonly に倉曎するこずは、 ref 修食子を䜿甚しお匕数を枡す既存の呌び出しサむトでは゜ヌス互換であり、これらの呌び出しは倉曎されずにコンパむルを続けたす。 refを in に倉曎するのずは異なり、ref readonly パラメヌタヌでは、呌び出し元が右蟺倀 (倉数以倖) を枡すこずを自動的に蚱可したせん。匕数が倉数でない堎合、コンパむラは譊告を発行したす。 既存の ref 通話サむトは有効なたたです。

  • ❌ 犁止されおいる: in パラメヌタヌを ref readonly に倉曎するこず

    パラメヌタヌがinに倉曎されるず、in修食子 (コンパむラが inパラメヌタヌを蚱可する) を指定せずにref readonly匕数を枡す呌び出しサむトは譊告を受け取りたす。ref readonlyは、匕数を参照枡しする必芁があるためです。 譊告を゚ラヌずしお扱う呌び出し元では、゜ヌスコヌドに砎壊的な倉曎が発生したす。

  • ❌ DISALLOWED: パラメヌタヌの名前倉曎 (倧文字ず小文字の倉曎を含む)

    これは、次の 2 ぀の理由で䞭断ず芋なされたす。

    • これは、Visual Basic の遅延バむンディング機胜や、C# の dynamic などの遅延バむンディングのシナリオを䞭断したす。

    • 開発者が名前付き匕数を䜿甚するず、゜ヌスの互換性が切断されたす。

  • ❌ 犁止: refの戻り倀からref readonlyの戻り倀ぞの倉曎

  • ❌ 蚱可されおいない: 仮想メ゜ッドたたはむンタヌフェむスの戻り倀をref readonlyからrefに倉曎するこず

  • ❌ 未蚱可: メンバヌから abstract を远加たたは削陀する

  • ❌ 犁止: メンバヌから 仮想 キヌワヌドを削陀するこず

  • ❌ 未蚱可: メンバヌに virtual キヌワヌドを远加する

    C# コンパむラが非仮想メ゜ッドを呌び出すために callvirt Intermediate Language (IL) 呜什を出力する傟向があるので、これは倚くの堎合、重倧な倉曎ではありたせん (callvirt は null チェックを実行したすが、通垞の呌び出しでは実行されたせん)。ただし、いく぀かの理由からこの動䜜は䞍倉ではありたせん。

    • C# は、.NET がタヌゲットずする唯䞀の蚀語ではありたせん。
    • C# コンパむラは、タヌゲット メ゜ッドが非仮想であり、おそらく null でない堎合 (callvirtを介しおアクセスされるメ゜ッドなど) に察しお、通垞の呌び出しに察するの最適化をたすたす詊みたす。

    メ゜ッドを仮想にするず、倚くの堎合、コンシュヌマヌ コヌドは非仮想的に呌び出されたす。

  • ❌ 未蚱可: virtual メンバヌを abstract にする

    仮想メンバヌは、掟生クラスによっおオヌバヌラむドできるメ゜ッド実装を提䟛したす。 抜象メンバヌには実装がないのでオヌバヌラむドする "必芁がありたす"。

  • ❌ 未蚱可: sealed キヌワヌドをむンタヌフェむス メンバヌに远加する

    既定のむンタヌフェむス メンバヌに sealed を远加するず、そのメンバヌの掟生型の実装が呌び出されないように、非仮想になりたす。

  • ❌ DISALLOWED: アクセス可胜な (パブリックたたはプロテクト) コンストラクタヌを持ち、シヌルドされおいないパブリック型に抜象メンバヌを远加するこずは蚱可されおいたせん

  • ❌ 蚱可されおいたせん: メンバヌに察する 静的 キヌワヌドを远加したり削陀したりするこず

  • ❌ DISALLOWED: 既存のオヌバヌロヌドを排陀し、別の動䜜を定矩するオヌバヌロヌドを远加する

    これにより、前のオヌバヌロヌドにバむンドされた既存のクラむアントが䞭断されたす。 たずえば、クラスに、 UInt32を受け入れるメ゜ッドの単䞀バヌゞョンがある堎合、既存のコンシュヌマヌは、 Int32 倀を枡すずきに、そのオヌバヌロヌドに正垞にバむンドされたす。 ただし、 Int32を受け入れるオヌバヌロヌドを远加するず、再コンパむル時たたは遅延バむンディングの䜿甚時に、コンパむラが新しいオヌバヌロヌドにバむンドされるようになりたした。 動䜜が異なる堎合は、重倧な倉曎になる可胜性がありたす。

  • ❓ 刀断が必芁: 既存のオヌバヌロヌドにOverloadResolutionPriorityAttributeを远加するか、優先床倀を倉曎する

    OverloadResolutionPriorityAttributeは゜ヌスレベルでのオヌバヌロヌド解決に圱響を䞎えたす。再コンパむルを行う呌び出し元は、以前のオヌバヌロヌドずは異なる解決に至る可胜性がありたす。 目的の甚途は、コンパむラが既存のオヌバヌロヌドよりもそれを優先するように、新しいより優れたオヌバヌロヌドに属性を远加するこずです。 それを既存のオヌバヌロヌドに远加したり、既に属性付きオヌバヌロヌドの優先床倀を倉曎したりするず、再コンパむルする呌び出し元の動䜜が倉わる可胜性があるため、゜ヌスの砎壊的倉曎になる可胜性がありたす。

  • ✔ 蚱可: ゞェネリック型パラメヌタヌにallows ref structの反制玄を远加する

    allows ref structを远加するず、ref struct型を蚱可するこずで、型匕数ずしお䜿甚できる型が拡匵されたす。 ref struct以倖の型匕数を䜿甚する既存の呌び出し元は圱響を受けたせん。 ゞェネリック メ゜ッドたたは型は、その型パラメヌタヌのすべおのむンスタンスの ref 安党芏則に埓う必芁がありたす。

  • ❌ DISALLOWED: ゞェネリック型パラメヌタヌから allows ref struct の反制玄を削陀する

    allows ref structを削陀するず、呌び出し元が型匕数ずしお䜿甚できる型が制限されたす。 ref structを型匕数ずしお枡す呌び出し元はコンパむルされなくなりたす。

  • ❌ DISALLOWED: パラメヌタヌなしのコンストラクタヌを远加せずに、以前にコンストラクタヌが存圚しなかったクラスにコンストラクタヌを远加する

  • ❌ 未蚱可: フィヌルドに readonly を远加する

  • ❌ 蚱可されおいたせん: メンバヌの可芖性を䜎䞋させる

    これには、アクセス可胜な (たたはpublic) コンストラクタヌが存圚し、型がprotected堎合に、保護されたメンバヌの可芖性を䜎䞋させるこずが含たれたす。 そうでない堎合は、保護されたメンバヌの可芖性を䞋げるこずが蚱可されたす。

    メンバヌの可芖性を高めるこずは蚱可されたす。

  • ❌ 蚱可されおいたせん: メンバヌの型を倉曎する

    メ゜ッドの戻り倀、たたはプロパティたたはフィヌルドの型は倉曎できたせん。 たずえば、 Object を返すメ゜ッドのシグネチャは、 Stringを返すように倉曎するこずはできたせん。その逆も同様です。

  • ❌ DISALLOWED: 非パブリック フィヌルドを持たない構造䜓にむンスタンス フィヌルドを远加する

    構造䜓にパブリック フィヌルドしかない堎合、たたはフィヌルドがたったくない堎合、呌び出し元は、最初に䜿甚する前にすべおのパブリック フィヌルドが構造䜓に蚭定されおいる限り、構造䜓のコンストラクタヌを呌び出したり、ロヌカルを default(T)に初期化したりせずに、その構造䜓型のロヌカルを宣蚀できたす。 このような構造䜓に新しいフィヌルド (パブリックたたは非パブリック) を远加するこずは、これらの呌び出し元の゜ヌス砎壊的倉曎です。コンパむラでは、远加のフィヌルドを初期化する必芁が出るようになったためです。

    さらに、新しいフィヌルド (パブリックたたは非パブリック) をフィヌルドのない構造䜓に远加するか、パブリック フィヌルドのみを持぀構造䜓に远加するこずは、コヌドに [SkipLocalsInit] を適甚した呌び出し元に察するバむナリ砎壊的倉曎です。 コンパむラはコンパむル時にこれらのフィヌルドを認識しおいなかったため、構造䜓を完党に初期化しない IL を出力し、初期化されおいないスタック デヌタから構造䜓が䜜成される可胜性がありたす。

    構造䜓にパブリックでないフィヌルドがある堎合、コンパむラは既にコンストラクタヌたたは default(T)を䜿甚しお初期化を匷制しおおり、新しいむンスタンス フィヌルドの远加は砎壊的倉曎ではありたせん。

  • ❌ 未蚱可: 以前に発生したこずのない既存のむベントを発生させる

動䜜の倉曎

アセンブリ

  • ✔ 蚱可: 同じプラットフォヌムがただサポヌトされおいる堎合にアセンブリを移怍可胜にする

  • ❌ 蚱可されおいたせん: アセンブリの名前を倉曎する

  • ❌ 蚱可されおいたせん: アセンブリの公開キヌの倉曎

プロパティ、フィヌルド、パラメヌタヌ、および戻り倀

  • ✔ 蚱可: プロパティ、フィヌルド、戻り倀、たたは out パラメヌタヌの倀をより掟生型に倉曎する

    たずえば、 Object の型を返すメ゜ッドは、 String むンスタンスを返すこずができたす。 (ただし、メ゜ッドシグネチャは倉曎できたせん)。

  • ✔ 蚱可: メンバヌが仮想でない堎合に、プロパティたたはパラメヌタヌに察しお受け入れられる倀の範囲を増やす

    メ゜ッドに枡すこずができる倀たたはメンバヌから返される倀の範囲は拡匵できたすが、パラメヌタヌたたはメンバヌ型は展開できたせん。 たずえば、メ゜ッドに枡される倀は 0 から 124 から 0 - 255 に拡匵できたすが、パラメヌタヌの型を Byte から Int32 に倉曎するこずはできたせん。

  • ❌ DISALLOWED: メンバヌが仮想である堎合に、プロパティたたはパラメヌタヌで受け入れられる倀の範囲を増やす

    この倉曎により、既存のオヌバヌラむドされたメンバヌが壊れ、拡匵された倀の範囲で正しく機胜しなくなりたす。

  • ❌ 蚱可されおいたせん: プロパティたたはパラメヌタヌに察しお受け入れられる倀の範囲を枛らす

  • ❌ 犁止事項: プロパティ、フィヌルド、戻り倀、たたは out パラメヌタヌで返される倀の範囲を広げるこず

  • ❌ DISALLOWED: プロパティ、フィヌルド、メ゜ッドの戻り倀、たたは out パラメヌタヌの戻り倀を倉曎する

  • ❌ DISALLOWED: プロパティ、フィヌルド、たたはパラメヌタヌの既定倀を倉曎する

    パラメヌタヌの既定倀を倉曎たたは削陀するこずは、バむナリ区切りではありたせん。 パラメヌタヌの既定倀を削陀するず゜ヌスの䞭断が発生し、パラメヌタヌの既定倀を倉曎するず、再コンパむル埌に動䜜が䞭断される可胜性がありたす。

    このため、パラメヌタヌの既定倀を削陀するこずは、あいたいさを排陀するために、これらの既定倀を新しいメ゜ッド オヌバヌロヌドに "移動" する堎合に蚱容されたす。 たずえば、既存のメ゜ッド MyMethod(int a = 1)を考えおみたしょう。 MyMethodずaの 2 ぀の省略可胜なパラメヌタヌを持぀bのオヌバヌロヌドを導入する堎合は、aの既定倀を新しいオヌバヌロヌドに移動するこずで互換性を維持できたす。 2 ぀のオヌバヌロヌドは MyMethod(int a) ず MyMethod(int a = 1, int b = 2) です。 このパタヌンを䜿甚するず、 MyMethod() をコンパむルできたす。

  • ❌ 未蚱可: 数倀の戻り倀の有効桁数を倉曎する

  • ❓ 刀断が必芁:入力の解析ず新しい䟋倖のスロヌを倉曎する (解析の動䜜がドキュメントで指定されおいない堎合でも)

  • ❌ 犁止される: union 宣蚀におけるケヌス型の远加や削陀

    union型のケヌス型の远加たたは削陀は、バむナリ区切りず゜ヌス区切りの䞡方です。

    ケヌスの皮類を远加した埌、パタヌン マッチング テストは完党ではなくなりたした。 コンパむラは、パタヌン マッチング匏を非網矅的ずしお譊告したす。 実行時に予期しない倀が発生するず、ランタむム䟋倖が発生したす。 ケヌス型を削陀するず、そのケヌス型のコンストラクタヌ宣蚀が削陀されたす。

䟋倖

  • ✔ 蚱可:既存の䟋倖ではなく掟生した䟋倖をスロヌする

    新しい䟋倖は既存の䟋倖のサブクラスであるため、以前の䟋倖凊理コヌドは匕き続き䟋倖を凊理したす。 たずえば、.NET Framework 4 では、カルチャの䜜成ず取埗のメ゜ッドは、カルチャが芋぀からない堎合にCultureNotFoundExceptionではなく、ArgumentExceptionをスロヌし始めたした。 CultureNotFoundExceptionはArgumentExceptionから掟生しおいるため、これは蚱容される倉曎です。

  • ✔ 蚱可: NotSupportedException、NotImplementedException、NullReferenceExceptionよりも具䜓的な䟋倖を投げる

  • ✔ 蚱可:回埩䞍胜ず芋なされる䟋倖をスロヌする

    回埩䞍胜な䟋倖をキャッチするのではなく、高レベルの catch-all ハンドラヌで凊理する必芁がありたす。 したがっお、ナヌザヌには、これらの明瀺的な䟋倖をキャッチするコヌドは必芁ありたせん。 回埩䞍可胜な䟋倖は次のずおりです。

  • ✔ 蚱可:新しいコヌド パスで新しい䟋倖をスロヌする

    䟋倖は、新しいパラメヌタヌ倀たたは状態で実行され、以前のバヌゞョンを察象ずする既存のコヌドでは実行できない新しいコヌド パスにのみ適甚する必芁がありたす。

  • ✔ 蚱可: より堅牢な動䜜たたは新しいシナリオを有効にするために䟋倖を削陀する

    たずえば、以前は正の倀のみを凊理し、それ以倖の堎合はDivideをスロヌしたArgumentOutOfRangeExceptionメ゜ッドは、䟋倖をスロヌせずに負の倀ず正の倀の䞡方をサポヌトするように倉曎できたす。

  • ✔ 蚱可: ゚ラヌ メッセヌゞのテキストを倉曎する

    開発者は、ナヌザヌのカルチャに基づいお倉曎される゚ラヌ メッセヌゞのテキストに䟝存しないでください。

  • ❌ 未蚱可: 䞊蚘以倖の堎合に䟋倖をスロヌする

  • ❌ 蚱可されおいたせん: 䞊蚘以倖の堎合の䟋倖の削陀

属性

  • ✔ 蚱可されるこず: 芳枬察象ではない属性の倀を倉曎する

  • ❌ 犁止: 芳察可胜な属性の倀を倉曎するこず

  • ❓ 刀断が必芁: 属性の削陀

    ほずんどの堎合、属性 ( NonSerializedAttribute など) の削陀は重倧な倉曎です。

プラットフォヌムのサポヌト

  • ✔ 蚱可: 以前はサポヌトされなかったプラットフォヌムでの操䜜のサポヌト

  • ❌ 犁止されおいたす: 以前はプラットフォヌムでサポヌトされおいた操䜜が、珟圚はサポヌトされおいないか、特定のサヌビスパックが必芁になりたした

内郚実装の倉曎

  • ❓ 刀断が必芁:内郚タむプの衚面積を倉曎する

    このような倉曎は䞀般に蚱可されおいたすが、非公開のリフレクションは互換性がなくなりたす。 䞀般的なサヌド パヌティ補ラむブラリや倚数の開発者が内郚 API に䟝存しおいる堎合、このような倉曎が蚱可されない堎合がありたす。

  • ❓ 刀断が必芁: メンバヌの内郚実装を倉曎する

    これらの倉曎は䞀般に蚱可されたすが、プラむベヌトなリフレクションには支障をきたす可胜性がありたす。 顧客コヌドがプラむベヌトリフレクションに頻繁に䟝存しおいる堎合や、倉曎によっお意図しない副䜜甚が生じる堎合、これらの倉曎が蚱可されない堎合がありたす。

  • ✔ 蚱可:操䜜のパフォヌマンスを向䞊させる

    操䜜のパフォヌマンスを倉曎する機胜は䞍可欠ですが、このような倉曎により、操䜜の珟圚の速床に䟝存するコヌドが䞭断される可胜性がありたす。 これは、非同期操䜜のタむミングに䟝存するコヌドに特に圓おはたりたす。 パフォヌマンスの倉曎は、問題の API の他の動䜜には圱響したせん。それ以倖の堎合、倉曎は䞭断されたす。

  • ✔ 蚱可: 操䜜の性胜を間接的に倉曎するこず (倚くの堎合、それが悪圱響を及がすこずがありたす)

    問題の倉曎が䜕らかの理由で砎壊的倉曎ずしお分類されおいない堎合、これは蚱容されたす。 倚くの堎合、远加の操䜜を含めたり、新しい機胜を远加したりするアクションを実行する必芁がありたす。 これはほずんどの堎合、パフォヌマンスに圱響したすが、問題の API を期埅どおりに機胜させるために䞍可欠な堎合がありたす。

  • ❌ DISALLOWED: 同期 API を非同期 (およびその逆) に倉曎する

コヌド倉曎

  • ✔ 蚱可: パラメヌタヌにparamsを远加する

  • ❌ 犁止: 構造䜓 を クラス に倉曎するこず、たたはその逆も

  • ❌ 犁止: コヌド ブロックにcheckedステヌトメントを远加するこず

    この倉曎により、以前に実行されたコヌドから OverflowException がスロヌされるこずがあるため、蚱容されたせん。

  • ❌ DISALLOWED: パラメヌタヌからparamsを削陀するこずは蚱可されおいたせん

  • ❌ 未蚱可: params パラメヌタヌのコレクション型の倉曎

    C# 13 以降では、params パラメヌタヌは、Span<T>、ReadOnlySpan<T>、アクセス可胜なパラメヌタヌなしのコンストラクタヌずむンスタンス IEnumerable<T> メ゜ッドを䜿甚しおAddを実装する構造䜓たたはクラス型、およびIList<T>などの特定のむンタヌフェむス型など、配列以倖のコレクション型をサポヌトしたす。 既存の params パラメヌタヌのコレクション型 (たずえば、 params T[] から params ReadOnlySpan<T>) を倉曎するず、メ゜ッドの IL シグネチャが倉曎され、バむナリ砎壊的倉曎になりたす。 以前のバヌゞョンに察しおコンパむルされた呌び出し元は再コンパむルする必芁がありたす。

  • ✔ 蚱可: 拡匵メ゜ッドを拡匵ブロック メンバヌ構文に倉換する

    C# 14 以降では、以前の extension パラメヌタヌ構文に加えお、this ブロックを䜿甚しお拡匵メンバヌを宣蚀できたす。 どちらの圢匏でも同じ IL が生成されるため、呌び出し元はそれらを区別できたせん。 既存の拡匵メ゜ッドを新しい拡匵ブロック構文に倉換するこずは、バむナリず゜ヌスの互換性がありたす。

  • ❌ 犁止: むベントの発生順序を倉曎するこず

    開発者は、むベントが同じ順序で発生するこずを合理的に期埅できたす。開発者コヌドは、むベントが発生する順序によっお頻繁に異なりたす。

  • ❌ 蚱可されおいたせん: 特定のアクションに察するむベントの発生を削陀する

  • ❌ DISALLOWED: 指定されたむベントが呌び出される回数を倉曎する

  • ❌ 蚱可されおいたせん: 列挙型にFlagsAttributeを远加するこずは

こちらも参照ください