C# の ==、Equals()、ReferenceEquals() の違いを一度に理解する
まず CLR の基本的な値の型間の比較を見て、最初にコードを見てみましょう:
int age1 = 30; int age2 = 30; Console.WriteLine("int == int: {0}", age1 == age2); Console.WriteLine("int == int: {0}", age2 == age1); Console.WriteLine("int Equals int: {0}", age1.Equals(age2)); Console.WriteLine("int Equals int: {0}", age2.Equals(age1)); Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age1, age2)); Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age2, age1)); Console.ReadLine();
実行結果:
同じ基本的な値の型 (上記のコード例ではすべて int) の場合、== とEquals() 値型の場合、ReferenceEquals() は 2 つのオブジェクトの参照が等しいかどうかを判断するため、比較結果は同じです。これは、各判断の前にボックス化操作を実行する必要があるためです。つまり、毎回一時オブジェクトが生成されます。したがって、 false を返すことはありません。次に、コード内の age2 の型をバイト型に変更すると、比較結果はどうなるでしょうか。実行結果を見てください:
age1.Equals(age2) と age2.Equals(age1) の結果が異なることがわかります。基本的な値の型の比較では、== は「値」の内容を比較します。2 つのオブジェクトの「値」が同じである場合、2 つのオブジェクトは「==」になりますが、Equals() はそれ以上のことを行います。実はEqual()には「暗黙的な変換」の処理があり、上のコードのage1.Equals(age2)はint.Equals(int)と等価であり、バイトデータを暗黙的にInt型データに変換できるということです。したがって、age1.Equals(age2) の結果は true となり、age2.Equals(age1) は byte.Equals(byte) と等価になりますが、int 型データは暗黙的に byte 型に変換できません。データの精度。実際、age2.Equals(age1) の Equals() は次のコードのようになります:
public override bool Equals(object obj) { if (!(obj is Byte)) { return false; } return m_value == ((Byte)obj).m_value; }
明示的な変換の場合、この時点では age2.Equals((byte)age1) の結果は true になります。 。
文字列型間の比較について話しましょう。文字列は「不変」であるため、特別な参照型です。まずコードを見てみましょう:
string name1 = "Jack"; string name2 = "Jack"; object o1 = name1; object o2 = name2; Console.WriteLine("name1 == name2: {0}", name1 == name2); Console.WriteLine("name1 Equals name2: {0}", name1.Equals(name2)); Console.WriteLine("o1 == o2: {0}", o1 == o2); Console.WriteLine("o1 Equals o2: {0}", o1.Equals(o2)); Console.WriteLine("o1 == name2: {0}", o1 == name2); Console.WriteLine("o1 Equals name2: {0}", o1.Equals(name2)); Console.WriteLine("name1 ReferenceEquals name2: {0}", object.ReferenceEquals(name1, name2)); Console.WriteLine("o1 ReferenceEquals o2: {0}", object.ReferenceEquals(o1, o2)); Console.ReadLine();
上記のコードの実行結果:
比較結果はすべて真です。これから 1 つずつ説明します。 name1 と name2 は両方とも "Jack" を格納しているため、name1 と name2 は実際には同じオブジェクトであるため、name1==name2 と name1.Equals(name2) の比較結果は同じであると言う人もいます。おそらく、その考えは正しいでしょう。 .NET Reflector ツールで文字列のソース コードを表示すると、次のコード部分が表示されます:
演算子 == は実際には Equals() を返します。したがって、name1==name2 と name1.Equals(name2) の比較結果が同じになる理由の説明は、「name1 と name2 は実際には同じオブジェクトである」よりも、この説明の方が直感的だと思います。
文字列型の特殊性により、CLR は文字列オブジェクトを通じて複数の同一の文字列コンテンツを共有できることがわかっています。そのため、上記の name1 と name2 は同じ場所を指し、次の o1 == o2、o1 == name2 と object.ReferenceEquals(name1, name2) の比較結果はどちらも true であり、このステートメントも検証されます (実際、object.ReferenceEquals(name1, o2) も true です)。しかし、name1 と name2 の割り当てが次のようになったらどうなるでしょうか?
string name1 = new string(new char[] { 'J', 'a', 'c', 'k' }); string name2 = new string(new char[] { 'J', 'a', 'c', 'k' });
実行結果を見てください:
name1==name2 と name1.Equals(name2) の比較結果は、理解しやすいものです。 上で述べたように、operator== は実際には Equals() (For の場合) を返します。参照型の場合、Equals() はマネージド ヒープに格納されている内容を比較するため、結果は同じになります。ただし、オブジェクト o1 と o2 を比較すると、o1 == o2 と o1.Equals(o2) の結果は異なります。 == of object オブジェクトは型オブジェクト ポインターを比較します。o1 と o2 は 2 つのオブジェクトであり、それらの型オブジェクト ポインターは異なる必要があります。Equals() はマネージド ヒープに格納されている o1 と o2 の内容を比較するため、o1.Equals (o2) は次のようになります。真実。これは、次の o1 == name2 が false であり、o1.Equals(name2) が true であることも示しています。
まず object.ReferenceEquals の内部コードを見てみましょう:
これで、object.ReferenceEquals(name1, name2) と object.ReferenceEquals(o1, o2) の結果が次のようになることを簡単に理解できるはずです。どちらも false です。実際には、これらはオブジェクトの 2 つの == 問題です。
最後に、カスタム参照型の比較について話しましょう。
class MyName { private string _id; public string Id { get { return _id; } set { _id = value; } } public MyName(string id) { this.Id = id; } }
上記の name1 と name2 の宣言を次のように変更します。
MyName name1 = new MyName("12"); MyName name2 = new MyName("12");
その他は変更されず、実行結果は次のようになります。
name1 と name2 は 2 つの完全に異なるオブジェクトです。比較結果がすべて false であることは簡単に理解できるはずです。
C# の ==、Equals()、ReferenceEquals() の違いを一度に理解するための関連記事については、PHP 中国語 Web サイトに注目してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









c言語のシンボルの使用方法は、算術、割り当て、条件、ロジック、ビット演算子などをカバーします。算術演算子は基本的な数学的操作に使用されます。割り当てと追加、下位、乗算、除算の割り当てには、条件操作に使用されます。ポインター、ファイル終了マーカー、および非数値値。

マルチスレッドと非同期の違いは、マルチスレッドが複数のスレッドを同時に実行し、現在のスレッドをブロックせずに非同期に操作を実行することです。マルチスレッドは計算集約型タスクに使用されますが、非同期はユーザーインタラクションに使用されます。マルチスレッドの利点は、コンピューティングのパフォーマンスを改善することですが、非同期の利点はUIスレッドをブロックしないことです。マルチスレッドまたは非同期を選択することは、タスクの性質に依存します。計算集約型タスクマルチスレッド、外部リソースと相互作用し、UIの応答性を非同期に使用する必要があるタスクを使用します。

Char Arrayは文字シーケンスをC言語で保存し、char array_name [size]として宣言されます。アクセス要素はサブスクリプト演算子に渡され、要素は文字列のエンドポイントを表すnullターミネーター「\ 0」で終了します。 C言語は、strlen()、strcpy()、strcat()、strcmp()など、さまざまな文字列操作関数を提供します。

Cでは、文字列でCharタイプが使用されます。1。単一の文字を保存します。 2。配列を使用して文字列を表し、ヌルターミネーターで終了します。 3。文字列操作関数を介して動作します。 4.キーボードから文字列を読み取りまたは出力します。

C言語では、以下などのエスケープシーケンスを通じて特殊文字が処理されます。\ nはラインブレークを表します。 \ tはタブ文字を意味します。 ESACEシーケンスまたは文字定数を使用して、Char C = '\ n'などの特殊文字を表します。バックスラッシュは2回逃げる必要があることに注意してください。さまざまなプラットフォームとコンパイラが異なるエスケープシーケンスを持っている場合があります。ドキュメントを参照してください。

C言語では、charタイプの変換は、キャスト:キャスト文字を使用することにより、別のタイプに直接変換できます。自動タイプ変換:あるタイプのデータが別のタイプの値に対応できる場合、コンパイラは自動的に変換します。

C言語に組み込みの合計機能はないため、自分で書く必要があります。合計は、配列を通過して要素を蓄積することで達成できます。ループバージョン:合計は、ループとアレイの長さを使用して計算されます。ポインターバージョン:ポインターを使用してアレイ要素を指し示し、効率的な合計が自己概要ポインターを通じて達成されます。アレイバージョンを動的に割り当てます:[アレイ]を動的に割り当ててメモリを自分で管理し、メモリの漏れを防ぐために割り当てられたメモリが解放されます。

C言語では、charとwchar_tの主な違いは文字エンコードです。CharはASCIIを使用するか、ASCIIを拡張し、WCHAR_TはUnicodeを使用します。 Charは1〜2バイトを占め、WCHAR_Tは2〜4バイトを占有します。 charは英語のテキストに適しており、wchar_tは多言語テキストに適しています。 CHARは広くサポートされており、WCHAR_TはコンパイラとオペレーティングシステムがUnicodeをサポートするかどうかに依存します。 CHARの文字範囲は限られており、WCHAR_Tの文字範囲が大きく、特別な機能が算術演算に使用されます。
