56

「ほぼ」すべてがオブジェクトであるという論争を解決するのを手伝ってください(スタック オーバーフローの質問への回答初心者として、C# を学ぶ前に注意すべきことはありますか? )。Visual Studio のすべてが少なくとも構造体として表示されるため、これが当てはまると思いました。「現代ジャッカス」( This American Life )にならないように参考に投稿してください。

この質問は、必ずしも .NET ではなく C# に関するものであり、内部でデータを処理する方法 (明らかに、すべて 1 と 0 です) に関するものであることに注意してください。

「すべてがオブジェクトである」に対するコメントは次のとおりです。

  • いえいえ、違います。– バイナリウォリアー
  • 例が欲しい... – scotty2012
  • すべてが基本型 Object から派生したものではないですか? – リズル
  • ほとんどのものはオブジェクトです... – Omar Kooheji
  • 値型、int、double、オブジェクト参照 (オブジェクト自体ではない) などはオブジェクトではありません。オブジェクトのように「ボックス化」することもできます (egiToString()) が、実際にはプリミティブ型です。エントリを「ほぼすべてがオブジェクトである」に変更し、反対票を削除します – Binary Worrier
  • 明確にしていただきありがとうございます。C# で対話できる最も低いレベル、たとえば int は、オブジェクトではない構造体であると思いますか? - http://msdn.microsoft.com/en-us/library/ms173109.aspx - リズル
  • Int32 は Object を継承する ValueType を継承していませんか? その場合、動作にかかわらず、int はオブジェクトです。– クリス・ファーマー
  • いいえ、int のボックス化された型は、Object を継承する ValueType を継承します。a) int は int への参照ではなく、それは int であるため、従来の意味でのオブジェクトではありません。b) int はガベージ コレクションされません。Int32 を宣言すると、その int はスタック上で 4 バイトになります。話の終わり – Binary Worrier

オブジェクトの定義: クラス System.Object の継承者としての「オブジェクト」 vs. 型のインスタンスとしての「オブジェクト」 vs. 参照型としての「オブジェクト」。

4

17 に答える 17

81

ここでの問題は、これが実際には 2 つの質問であることです。1 つの質問は継承に関するもので、この場合の答えは「ほぼすべて」であり、もう 1 つの質問は参照型と値型/メモリ/ボクシングに関するものであり、この場合の答えは「いいえ」です。 "。

継承:

C# では、次のことが当てはまります。

  • 列挙型や null 許容型を含むすべての値型は、から派生していSystem.Objectます。
  • すべてのクラス、配列、およびデリゲート型は から派生していSystem.Objectます。
  • インターフェイス タイプは から派生していませんSystem.Object。それらはすべて に変換可能System.Objectですが、インターフェイスは他のインターフェイス タイプからのみ派生し、インターフェイス タイプでSystem.Objectはありません。
  • から派生するポインタ型System.Objectはなく、直接変換できるものもありませんSystem.Object
  • 「オープン」タイプのパラメータ タイプも から派生していませんSystem.Object。型パラメーターの型は、何からも派生しません。型引数は有効な基本クラスから派生するように制約されていますが、それら自体は何からも「派生」していません。

System.Object の MSDN エントリから:

.NET Framework クラス階層のすべてのクラスをサポートし、派生クラスに低レベルのサービスを提供します。これは、.NET Framework のすべてのクラスの最終的な基本クラスです。これは型階層のルートです。

継承は暗黙的であるため、通常、言語では Object からの継承をクラスで宣言する必要はありません。

.NET Framework のすべてのクラスは Object から派生しているため、Object クラスで定義されたすべてのメソッドは、システム内のすべてのオブジェクトで使用できます。派生クラスは、これらのメソッドの一部をオーバーライドできます。

したがって、C# のすべての型が から派生しているわけではありませんSystem.Objectこれらの型であっても、参照型値型の違いに注意する必要があります。これらは扱いが大きく異なるためです。

ボクシング:

値型はから継承System.Objectされますが、参照型とはメモリ内での扱いが異なり、コード内のメソッドを介して渡される方法のセマンティクスも異なります。実際、値型は、参照型としてボックス化することによってアプリケーションに明示的に指示するまで、オブジェクト (参照型) として扱われません。C# でのボクシングの詳細については、こちらを参照してください。

于 2009-01-12T17:29:53.773 に答える
31

パーティーには少し遅れましたが、SO の検索結果でこれに出会い、以下のリンクが将来の世代に役立つと考えました。

Eric Lippertは、これについて非常に徹底的に議論しており、より適切な (修飾された) ステートメントを使用しています。

この神話を修正する方法は、単に「派生元」を「変換可能」に置き換え、ポインター型を無視することです。C# のすべての非ポインター型はオブジェクトに変換可能です。

その要点は、プログラミング言語を書いている人からのよく説明された説明を読むのが嫌いなら、(ポインターは別として)、インターフェイス、またはジェネリックパラメーター型宣言 (「T」) のようなものはオブジェクトではなく、オブジェクトであることが保証されているということです。オブジェクトになる明確なインスタンスがあるため、実行時にオブジェクトとして扱うことができます。他のタイプ (Type、Enum、Delegate、クラスなど) はすべてオブジェクトです。他の回答で説明したように、オブジェクトにボックス化できる値の型を含めます。

于 2009-08-13T11:51:57.413 に答える
15

ここにいる何人かの人々は、オブジェクト指向プログラミングにおける「オブジェクト」とは何かについて奇妙な考えを持っています。何かをオブジェクトにするために、参照型である必要はなく、より一般的には、正式な実装に従う必要はありません。

つまり、オブジェクト指向の世界で一流の市民として操作できるということです。C# の値に対してこれを行うことができるため(オートボクシングのおかげで)、実際にはすべてがオブジェクトです。ある程度までは、これは関数にも当てはまります (しかし、おそらくクラスには当てはまりません)。

これが実際に関連するかどうかは別の問題ですが、これは OOP の一般的な問題であることに改めて気付きました。OOP の定義については誰も明確ではありません (そうです、ほとんどの人はそれがポリモーフィズム、継承、およびカプセル化と関係があることに同意しており、適切な手段として「抽象化」を取り入れている人もいます)。

使用の観点からは、C# のすべての値はオブジェクトのように処理されます。そうは言っても、私は現在受け入れられている答えが好きです。技術的に重要な両方の側面を提供します。

C++ などの他のコンテキストでは、C++ は必ずしもオブジェクト指向ではなく、さらに低レベルの側面に重点を置いているため、他の側面が強調されていることに注意してください。したがって、オブジェクト、POD、および組み込みプリミティブの区別は、場合によっては意味があります (ただし、場合によっては意味がありません)。

于 2009-01-12T18:05:47.367 に答える
8

オブジェクトを値または参照と混同しています。基本的に、すべてがオブジェクトです。Int はオブジェクトですが、値型でもあります。クラス インスタンスはオブジェクトですが、参照型でもあります。

メソッドはオブジェクトでもプロパティでもありません。オブジェクトを操作するだけです。はい、ほとんどすべてがオブジェクト クラスから継承されます。

于 2009-01-12T17:32:34.173 に答える
6

C# (および一般的な OOP) には、型 (クラス - 参照、構造体 - 値など) があります。これらは定義です。そして、「オブジェクト」は、特定の型の具体的なインスタンスです。

したがって、質問を文字通りに読むと、はい、インスタンス化されるとすべてがオブジェクトになります。

混乱はおそらく、すべての基本クラスの名前の選択が悪いことから始まります。.NET では、これは Object クラスです。

于 2009-01-12T17:41:24.093 に答える
5

それらはすべてオブジェクトとして扱われますが、すべてがオブジェクトではありません。混乱はオートボクシングで発生します。

詳細については、http: //en.wikipedia.org/wiki/Object_typeを参照してください。

抽象化は明らかに人々を混乱させます。

于 2009-01-12T17:40:45.407 に答える
4

値型はオブジェクトではないと思いました。それらは CLR によって異なる方法でメモリに格納されます。値の型はスタックに格納され、オブジェクトはヒープに格納されます。値型を参照型にキャストしてオブジェクトのように動作させることができますが、CLR はスタックから値を取得し、オブジェクトにラップして、ヒープに格納します。これは、変数を「ボックス化」したときに起こることです。

于 2009-01-12T17:34:42.610 に答える
4

From:値の型 (C# リファレンス) - MSDN 3.5

すべての値の型は、System.ValueType から暗黙的に派生します。

From:値型クラス - MSDN 3.5

ValueType は、値の型のより適切な実装で Object の仮想メソッドをオーバーライドします。

From: Enum クラス - MSDN 3.5

このクラスは ValueType から継承します

継承階層は次のとおりです。

  • System.Object
    • System.ValueType
      • System.Enum

結論:すべてはオブジェクトです

于 2009-01-12T18:09:58.437 に答える
3

私が読んだすべての本に基づくと、C# のすべてはオブジェクトです。

一部は参照であり、その他は値型です。値型オブジェクトはクラスValueTypeから継承します。それらは異なる動作をしますが、本質的に ... オブジェクトです。

これが、オブジェクト変数に Int32 を格納できるだけでなく、.NET で作成できるすべてのものを格納できる理由です。

詳細については...次を参照してください。 http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.71).aspx

すべての値の型は、Object クラスから暗黙的に派生します。

于 2009-01-12T17:31:02.290 に答える
3

誰もが値型と参照型の議論に注目しているように見えますが、参照でも値でもなく、オブジェクトから派生せず、オブジェクトにキャストできない C# の 1 つの型、つまりポインターを忘れています。

値や参照型とは異なり、ポインターはオブジェクトにキャストできません。

C# ポインター型に関する MSDN のドキュメントによると、

ポインター型はオブジェクトから継承されず、ポインター型とオブジェクトの間に変換は存在しません。また、ボックス化とボックス化解除はポインタをサポートしていません。ただし、異なるポインター型の間、およびポインター型と整数型の間で変換することはできます。

于 2009-01-13T17:05:32.683 に答える
2

簡単な答え:いいえ

その答えは、「オブジェクト」の定義にかかっています。「オブジェクト」の定義は言語ごとに異なりますが、C# の正式な定義は公式のC# 言語仕様です。

C# 言語の型は、参照型値型の 2 つの主なカテゴリに分けられます。(...) 値型の変数には直接データが含まれるのに対し、参照型の変数はデータへの参照を格納し、後者はオブジェクトとして知られているという点で、値型は参照型とは異なります。

したがって、C# によると、オブジェクトは参照型のインスタンスです。したがって、値型の値はオブジェクトではありません。したがって、すべてが C# のオブジェクトであるというのは正しくありません。

でも:

C# の型システムは、任意の型の値をオブジェクトとして扱うことができるように統一されています。(...) 値型の値は、ボックス化およびボックス化解除操作を実行することによってオブジェクトとして扱われます (§9.3.12)。

そのため、値型はボックス化することでオブジェクトとして扱うことができます(実質的に参照型に変わります)。ただし、ボックス化されていない値の型自体はオブジェクトではありません。

CLR 仕様[PDF] では、C# に非常によく似た定義が使用されています。

object : 参照型のインスタンス。オブジェクトには、値以上のものがあります。オブジェクトは自己型付けです。その型は、その表現に明示的に格納されます。他のすべてのオブジェクトと区別する ID があり、他のエンティティ (オブジェクトまたは値のいずれか) を格納するスロットがあります。スロットの内容は変更できますが、オブジェクトの ID は決して変更されません。

したがって、CLR 用語では、値型の値もオブジェクトではありません。

于 2009-01-13T16:52:19.700 に答える
1

セマンティクスに対処するために、「オブジェクト」という単語をオーバーロードして、「参照型」を意味するようにします。これは、「参照型」という完全に適切で明確な用語がすでに存在する場合と、「オブジェクト」という単語をオーバーロードする場合です。このようにして、このスレッドが示す混乱を引き起こします...つまり、すべての型(値型を含む)が型「System.Object」で定義された実装を継承するという事実間の不一致。明らかに、これはせいぜい不要であり、最悪の場合は非常に混乱します。MSのドキュメントがこの問題について混乱している場合でも、混乱を広める言い訳にはなりません。

はるかに簡単で明確なのは、「オブジェクト」という用語を定義して使用し、任意の型、値、または参照のインスタンスを意味し、「参照型」というフレーズを使用して、ポインター変数を使用し、その状態を格納する型を説明することです。ヒープ..。

于 2009-04-24T13:36:24.733 に答える
0

これは、言語と記憶という 2 つの世界の議論です。

私にとって言語は抽象化のレイヤーのようなものであり、オブジェクトという用語はこの抽象化のレベルに属します。メモリの構成という観点からオブジェクトについて話すことに意味がありません。メモリについて話すときに「オブジェクト」という用語を使用する場合、実際にはこの用語を別の抽象化層から借りていることになります。したがって、それがどこから来たのかを忘れてはなりません。

C# について話している場合、なぜ誰かがメモリ構成を引数として使用するのか理解できません。もちろん、私が誰かにこの質問に答えるなら、「はい、C# ではすべてがオブジェクトですが、内部では動作が異なる可能性があることも知っておく必要があります....」

これは興味深い議論を始めるかもしれませんが、一部の人に話すかもしれません. 同様の議論では、実際にはオブジェクト指向プログラミングはなく、手続き型プログラミングだけがあると言うことができます. CPU はオブジェクトを理解していますか? さらに良いことに、実際にはソフトウェアはなく、ハードウェアの状態が異なるだけです:)

私が言いたいのは、一部の用語は他の抽象化層に変換されないため、議論はそれが属する場所 (この場合は言語であり、記憶ではありません) に限定する必要があるということです。

この質問の作成者でさえ、次のように述べています。

于 2009-04-24T13:06:43.667 に答える
0

数字の 2 はオブジェクトではありません。

于 2009-01-12T17:31:31.260 に答える
-1

値型はオブジェクトではなく、異なるコピー セマンティクス、異なる受け渡しセマンティクスに従い、そのように扱うためにクラス (オブジェクト) にラップする必要があります。

編集:「オブジェクト」の意味を修飾する必要があるため、議論はやや曖昧だと思います。オブジェクトは単にオブジェクトから継承したものですか、それともオブジェクトの使用セマンティクスに従うものですか? それとも、オブジェクトの最も一般的な定義について話しているのでしょうか。つまり、データとそのデータに対する操作を含むことができるものです。

于 2009-01-12T17:31:16.453 に答える
-1

質問がOOPの意味でオブジェクトを参照していることを考えると、答えは次のとおりです。

技術的な観点からの答えは:いいえ

独断的な観点からの答えは:はい

説明:

技術的には、値型 (プリミティブまたは構造体) は「ボックス化された」形式でない限りオブジェクトではありませんが、.Net はボックス化/ボックス化解除 (値を保持するクラス インスタンスを作成し、は Object から派生しています)。これは、値の型をオブジェクトと単純な値の両方として扱うことができることを意味します。

したがって、値型は本質的に二重であり、としてもオブジェクトとしても動作します。.Net の値は、必要な場合はオブジェクトであり、それ以外の場合はオブジェクトではありません。

技術的な側面を考慮した正解は、「.Net 内のすべてがオブジェクトであるかのように」です。

独断的な答えは、「すべてはオブジェクトである」です。

于 2009-01-13T12:46:47.650 に答える