C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[14]: Object の比較についての疑問 [1]


(過去ログ 131 を表示中)

[トピック内 32 記事 (21 - 32 表示)]  << 0 | 1 >>

■77521 / inTopicNo.21)  Re[8]: Object の比較についての疑問
  
□投稿者/ WebSurfer (687回)-(2015/10/27(Tue) 10:04:58)
No77520 (ミルク さん) に返信
>
> 確実に理解しているかといわれると疑問ですけど
>
> 値型は変数が示す先にデータが保存されている。
> 参照型は変数が示す先にデータの保存領域が保存されているということぐらいです。

違うと言うことは理解されているようですが(確実な理解はググって調べていただく
として)、最初の質問の object, "10"(string 型)は参照型、10 (int 型)は値型
というところは理解されていますか。

その理解があれば、最初の質問に対しては私の一番最初のレスで紹介した以下の 2 つ
の記事が 100% 説明しています。

== 演算子 (C# リファレンス)
https://msdn.microsoft.com/ja-jp/library/53k8ybth.aspx

ボックス化とボックス化解除 (C# プログラミング ガイド)
https://msdn.microsoft.com/ja-jp/library/yz2be5wk.aspx

前者の記事の「使用例」の英文の説明(コメント)を見てください。

> obj1 = 10;
> obj2 = 10;

は、Reference equality: different objects, same boxed value: False. と説明さ
れているのと同じです。"boxed value" については紹介した記事の後者の方を読んで
ください。obj1 と obj2 は異なるオブジェクトを指すことが理解できるはずです。

> obj1 = "10";
> obj2 = "10";

は、Compare string references, both constants have the same value, so string
interning points to same reference: True.

と説明されているところと同じです。constants については No77511 他で他の回答者
の方が補足しているとおりで、前者の "10" と後者の "10" は同じオブジェクトとなり、
obj1 と obj2 は同じオブジェクトを指すことが分かるはずです。

引用返信 編集キー/
■77523 / inTopicNo.22)  Re[9]: Object の比較についての疑問
□投稿者/ furu (30回)-(2015/10/27(Tue) 13:20:30)
「たまたま派」です。

ご参考までに

https://msdn.microsoft.com/ja-jp/library/aa691090(v=vs.71).aspx

「リテラル文字列ごとに新しい文字列インスタンスが作成されるとは限りません。」
→作成されるかも

https://msdn.microsoft.com/ja-jp/library/dd183759.aspx

「同じアセンブリ内の定数文字列は、常に、実行時にインターンされます。
つまり、一意のリテラル文字列ごとにそのインスタンスが 1 つだけ保持されます。
ただし、ランタイムは実行時に作成された文字列がインターンされることを保証しません。
また、異なるアセンブリの 2 つの等しい定数文字列がインターンされることも保証しません。」
→保証しないだけでインターンされるかも


引用返信 編集キー/
■77524 / inTopicNo.23)  Re[10]: Object の比較についての疑問
□投稿者/ WebSurfer (689回)-(2015/10/27(Tue) 14:18:20)
No77523 (furu さん) に返信
> 「たまたま派」です。

> 「たまたま派」です。

どういう意味でしょうか? No77521 に私が書いたことと同じことを言ってますか?

それとも、そうではなくて、質問者さんの例、

> object obj1, obj2;
> obj1 = "10";
> obj2 = "10";

で、obj1 と obj 2 が同じオブジェクトを指していたのは「たまたま」で、違うケース
もあると言っています? そして、その根拠は紹介した記事だということですか?

引用返信 編集キー/
■77525 / inTopicNo.24)  Re[11]: Object の比較についての疑問
□投稿者/ furu (31回)-(2015/10/27(Tue) 22:02:44)
No77524 (WebSurfer さん) に返信
> ■No77523 (furu さん) に返信
>>「たまたま派」です。
>
> どういう意味でしょうか? No77521 に私が書いたことと同じことを言ってますか?
>
リファレンスなどでも厳密に書かれているわけではないと
言いたかっただけです。

現時点のコンパイラでは、違うケースがないのかもしれないけど
同じ参照になるかどうか、あんまりあてにしないで考えたほうがいいと
たまたまそうなっているぐらいでいいんじゃないでしょうか。

object obj1 = Convert.ToString("1");
object obj2 = "1".ToString();
object obj3 = "1";

obj1とobj2とobj3は参照が一致しますが
このプログラムとリファレンスを見ただけで
ふつう一致と断言できますでしょうか。

DateTimeなどもプリミティブ型でリテラルがあったりしたら
こういうやっかりな問題が存在するのでしょうね。
引用返信 編集キー/
■77526 / inTopicNo.25)  Re[12]: Object の比較についての疑問
□投稿者/ WebSurfer (690回)-(2015/10/27(Tue) 22:44:52)
No77525 (furu さん) に返信
> ■No77524 (WebSurfer さん) に返信
>>■No77523 (furu さん) に返信
> >>「たまたま派」です。
>>
>>どういう意味でしょうか? No77521 に私が書いたことと同じことを言ってますか?
>>
> リファレンスなどでも厳密に書かれているわけではないと
> 言いたかっただけです。
>
> 現時点のコンパイラでは、違うケースがないのかもしれないけど
> 同じ参照になるかどうか、あんまりあてにしないで考えたほうがいいと
> たまたまそうなっているぐらいでいいんじゃないでしょうか。
>
> object obj1 = Convert.ToString("1");
> object obj2 = "1".ToString();
> object obj3 = "1";
>
> obj1とobj2とobj3は参照が一致しますが
> このプログラムとリファレンスを見ただけで
> ふつう一致と断言できますでしょうか。

話は噛み合っているでしょうか? そういう話をしているのではないと思ってます
けど。

少なくとも、

質問者さんが最初に書かれた例:

object obj1, obj2;
obj1 = "10";
obj2 = "10";
MessageBox.Show((obj1 == obj2).ToString());

私が回答した記事のサンプル:

string a = "hello";
string b = String.Copy(a);
string c = "hello";

// Compare string references, both constants
// have the same value, so string interning
// points to same reference: True.
Console.WriteLine((object)a == (object)c);

furu さんが紹介された前者の記事のサンプルコード:

object a = "hello";
object b = "hello";
System.Console.WriteLine(a == b);

については、furu さんが紹介された後者の記事の

"同じアセンブリ内の定数文字列は、常に、実行時にインターンされます。つまり、
一意のリテラル文字列ごとにそのインスタンスが 1 つだけ保持されます。"

と書いてあるとおりで、このスレッドはその議論のはずですよ。

引用返信 編集キー/
■77527 / inTopicNo.26)  Re[13]: Object の比較についての疑問
□投稿者/ アザース (1回)-(2015/10/28(Wed) 15:17:24)
途中から、どうでもいいことを議論しているような気がする。

簡単に言えば、リテラル文字列はコンパイラ側で最適化して同一メモリを参照する、
ということは皆さんの解説の通りなので、
これが質問者に対する答えに相違ないと思う。

でも、実際問題、この事実仕様(というか仕様)を、アプリ開発側で積極的に利用するかというと、
そんなことはまずないと思うし、意味のないことだと思う。

そもそも

>obj1 = "10";
>obj2 = "10";
>MessageBox.Show((obj1 == obj2).ToString());

のようなobj1・obj2の比較は普通は行わないし、
このような比較を保証するようなコーディングはすべきではないと思う。

そういう意味では、「たまたま」という認識でいた方が安全だと思うし、
妥当だと思う。
引用返信 編集キー/
■77529 / inTopicNo.27)  Re[14]: Object の比較についての疑問
□投稿者/ ミルク (8回)-(2015/10/29(Thu) 15:52:15)
みなさんどうもありがとうございます。

String は参照型なのに 参照比較しているにも関わらず結果が
値型と同じような動作をするからおかしく感じたのですが

結局string型(ボックス化したobject型)は
コンパイラが文字列の扱い方を変えているのですね。




解決済み
引用返信 編集キー/
■77530 / inTopicNo.28)  Re[15]: Object の比較についての疑問
□投稿者/ WebSurfer (691回)-(2015/10/29(Thu) 17:24:54)
No77529 (ミルク さん) に返信

> 結局string型(ボックス化したobject型)は
> コンパイラが文字列の扱い方を変えているのですね。

String 型は参照型なのでボックス化は関係ないです。

ボックス化というのは先に紹介した記事に書いてあるように、値型から object 型
へ変換するプロセスのことです。最初の方だけでいいのでよく読んでください。

ボックス化とボックス化解除 (C# プログラミング ガイド)
https://msdn.microsoft.com/ja-jp/library/yz2be5wk.aspx

なので、ホントに理解されてはいないような気がするのですが・・・
引用返信 編集キー/
■77536 / inTopicNo.29)  Re[9]: Object の比較についての疑問
□投稿者/ アザース (2回)-(2015/10/30(Fri) 12:35:12)
> その理解があれば、最初の質問に対しては私の一番最初のレスで紹介した以下の 2 つ
> の記事が 100% 説明しています。
>
> == 演算子 (C# リファレンス)
> https://msdn.microsoft.com/ja-jp/library/53k8ybth.aspx

上のサイトの説明は、以下の(obj1 == obj2)がtrueであることの説明としては不十分だよ。
obj1もobj2も型はstringではなく、objectだからね。
そこは理解している?

> obj1 = "10";
> obj2 = "10";
> MessageBox.Show((obj1 == obj2).ToString());


引用返信 編集キー/
■77537 / inTopicNo.30)  Re[10]: Object の比較についての疑問
□投稿者/ WebSurfer (693回)-(2015/10/30(Fri) 12:50:20)
No77536 (アザース さん) に返信

あなたは何者?

何か個人的に言いたいことがあるなら、他人のスレッドで余計なノイズを増やす
のは止めて、自分で新たに別スレッドを立ててそこに書いてはいかが?

なお、捨てアカを使って匿名で書くのは卑怯者、なりすましはネットのクズと思
ってますので、自分はそのようなことをする人を相手に議論する気はありません。
なので、もし別スレッドを立てるならその点だけはよろしく。
引用返信 編集キー/
■77539 / inTopicNo.31)  Re[11]: Object の比較についての疑問
□投稿者/ アザース (3回)-(2015/10/30(Fri) 13:36:10)
> あなたは何者?

これにはびっくりした。
何者も何も、掲示板は一定のルールのもとに、自由な書き込みが保証されているはずだ。
私は77527と77536の書き込みしか行っていない。

このスレッドで議論されている事象について書き込みをしているのに
私の指摘に対して、卑怯者呼ばわりされるとは、ひどい話だ。
私とあなたとの間には、利害関係やうらみつらみがあるわけでもないのに。
ちょっと自己中心的過ぎやしないかい?
あなたの私に対しての書き込みこそ、余計なノイズというものなのではないのかい?

老婆心ながら、せめて、どぼんさんの所のようなトラブルだけは起こさないで欲しい。
引用返信 編集キー/
■77543 / inTopicNo.32)  Re[14]: Object の比較についての疑問
□投稿者/ 魔界の仮面弁士 (547回)-(2015/10/30(Fri) 14:41:19)
No77527 (アザース さん) に返信
>簡単に言えば、リテラル文字列はコンパイラ側で最適化して同一メモリを参照する、
>ということは皆さんの解説の通りなので、

質問ちゃんと読まずに、 No77490 で見当違いのこと書いてた私が通りますよ、っと。orz


// --------------------

object a = 10;    // Int32 である「10」は値型。
object b = 10;    // object 代入時にはボックス化される
object c = a;     // ボックス化されたオブジェクトへの参照をコピー

Console.WriteLine(b == a);   // (1) False :別々にボックス化されたものなので別参照
Console.WriteLine(c == b);   // (2) False :c は a であって、b ではない
Console.WriteLine();

// --------------------

object x1 = "10";  // String である "10" は参照型。参照型なのでボックス化は発生しない。
object y1 = "10";  // 文字列リテラルは、Intern Pool として同じ参照が共有される。
object z1 = x1;    // 

Console.WriteLine(y1 == x1);   // (3) True :文字列インターンプールにある同じ参照
Console.WriteLine(z1 == y1);   // (4) True :z1 は x1 であり、そして y1 でもある
Console.WriteLine();

// --------------------

object x2 = new String(new Char[] { '1', '0' });   // 文字列リテラルでは無いため、
object y2 = new String(new Char[] { '1', '0' });   // これらはインターンプールに入らない
object z2 = x2;

Console.WriteLine(y2 == x2);   // (5) False:インターンプールに無い個別の参照
Console.WriteLine(z2 == y2);   // (6) False:z2 は x2 であって、y2 ではない
Console.WriteLine();

object Y2 = String.IsInterned((String)y2);   // インターンプールを返す
object Z2 = String.IsInterned((String)z2);   // インターンプールを返す

Console.WriteLine(Y2 == y2);   // (7) False:元のインスタンスはインターンプールではなかった
Console.WriteLine(Y2 == Z2);   // (8) True :IsInterned により、共に同じインターンプールの参照が得られている
Console.WriteLine(Y2 == x1);   // (9) True :そしてそれは、最初の "10" への参照と同じものである
Console.WriteLine();

// --------------------

object o = new object();
object p = new object();
object q = o;

Console.WriteLine(p == o);   // (A) False :別々にインスタンス化された別参照
Console.WriteLine(p == q);   // (B) False :q は o であって、p ではない
Console.WriteLine();

// --------------------

引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -