4

作成するすべてのクラスは、そのクラスへの継承を明示的に宣言する必要なく、Object クラスから継承します。

  • Microsoft は、すべての .NET クラスを Object クラスから暗黙的に継承させるにはどうすればよいでしょうか?
  • コンパイラはその継承を舞台裏で注入しますか?
  • たとえば、すべてのクラスがクラス インターフェイスから暗黙的に継承されるようにすることはできますか?

私の質問があいまいかもしれないので、明確にします:

クラスの多重継承が禁止されていることはわかっているので、Object 以外の別のクラスからの継承については質問していません。クラス インターフェイスではなく継承について話しているのですが、私の質問は、オブジェクトを自分の別のクラスに置き換えることや、オブジェクトと自分の別のクラスで多重継承を行うことではなく、暗黙的にそれを行うことについてです。すべてのクラスが Interface1OfMyOwn および Interface2OfMyOwn から継承されるようにしたいと考えています。

4

4 に答える 4

11

ObjectC# 標準では言語がそのように指定されているため、すべてのクラスは暗黙的に拡張されます。

どのように実装したかを尋ねることは、voidメソッドがデータを返さないという事実をどのように実装したか、またはクラスがプロパティを持っているという事実をどのように実装したかを尋ねるようなものです: それは単にコンパイラのコードのどこかにあります (ここでは C# コンパイラかもしれません)または JIT コンパイラ)。確かなことはわかりませんが、コンパイラがクラスで明示的な継承を検出しない場合はいつでも、System.Object代わりに単純な継承を行うと言うのがもっともらしいです。Objectしたがって、これは単にコンパイラにとって特別な型であることを受け入れる必要があります。

カスタムクラスでそれができない理由は明らかです。明示的な継承のないクラスを拡張するObjectか、カスタムクラスを拡張するかについて、コンパイラを完全に混乱させるでしょう。明示的な継承のないすべてのクラスに対して後者を選択すると、ほとんどの場合コンパイル エラーが発生するか、特に運が悪い場合は、実行時にのみ現れる驚くべき動作が発生します。前者を選択し、これをクラスに明示的にオプトインする必要がある場合、ポイントは何ですか?

(もちろん、インターフェイスを暗黙的に実装したい場合にも同じことが起こります。そのインターフェイスを実際に実装していないすべてのクラスが壊れて、コンパイル エラーが発生します。または、運が悪いと、インターフェイスが無関係なメソッドに一致する可能性がありますたまたま一致するシグネチャを持ち、テストでわかる奇妙な動作を引き起こすクラスです。)

于 2013-05-26T11:57:32.890 に答える
6

これはランタイム内の非常に低いレベルでサポートされており、ガベージ コレクション ヒープに格納されているオブジェクトに値型の値を埋め込むことができます。したがって、値型を参照型に変換し、すべての値型が ValueType および Object から継承されているという錯覚を作成します。これは参照型です。

メカニズムは.NET でボクシングを呼び出しており、値の型の値は文字通り「ボックス化」されてオブジェクトになります。また、ボックス化された値を持つオブジェクトから値型の値に戻るためのボックス化解除変換があります。C# コンパイラは、ソース コードに基づいてこれらの変換を自動的に発行します。これには、C# コンパイラがソース コードから生成する中間言語である IL という専用のオペコードがあります。それぞれ Opcodes.Box および Opcodes.Unbox 命令。Opcodes.Constrained は、変換を最適化できる命令です。ジッターはそれらを実装する方法を知っており、これらの変換を行うための非常に効率的なインライン マシン コードを生成します。

ボックス化は、System.Object が型階層の基本クラスであることに非常に固有であり、それをサポートする配管は、値型の値に非常に固有です。これは拡張可能なメカニズムではありません。独自の IL 命令を追加したり、ジッターを拡張したり、C# 言語に新しい構文を与えたりすることはできません。型に共通の基本インターフェイスまたはクラスが必要な場合は、コードでそのように宣言する必要があります。dynamicキーワードはあなたにとって魅力的かもしれませんが、質問からは明確ではありません。

于 2013-05-26T12:29:40.340 に答える
3

提供された両方の回答に完全に同意します...目的の結果を達成するためにできるオプション、つまり「カスタムインターフェイスから自動的に継承する」を追加したかっただけです。

MS の Roslyn プロジェクトを使用すると、コンパイル プロセスを非常に詳細に制御できますが、Roslyn はまだ「本番環境に対応」していないことに注意してください。

コンパイル プロセスに影響を与えるコードを記述し、目的を達成するためにコンパイラがどのように動作するかを分析し、さらには変更することもできます。

検討する価値のあるもう 1 つのオプションは、AOP かもしれません。驚くべきことを実行できる .NET フレームワークがいくつかあります (たとえば、こちらを参照)。

于 2013-05-26T13:06:15.887 に答える
1

必要に応じて、拡張メソッドが機能しobjectます。すぐに失われる型情報が少ないジェネリック型を使用することもできます。

static class GeneralMethods
{
    public static void Testing(this object This)
    {
        This.ToString().Dump("Testing");
    }

    public static void Test2<T>(this T This)
    {
        This.Dump("Test2");
    }

}
于 2015-02-18T14:25:21.627 に答える