えムナウ Blog

えムナウ の なすがまま

目次

Blog 利用状況

ニュース


follow mnow at http://twitter.com


えムナウのプログラミングのページ

INETAJ

書庫

日記カテゴリ

ギャラリ

stringクイズ

直感で答えてください。

using System;

using System.Text;

 

namespace StringCheck

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("A");

            string s1 = "かるぼなら";

            string s2 = new StringBuilder().Append("かるぼ").Append("なら").ToString();

            CheckString(s1, s2);

            Console.WriteLine("B");

            string s3 = "かるぼ";

            s3 += "なら";

            CheckString(s1, s3);

            Console.WriteLine("C");

            string s4 = "かるぼなら";

            CheckString(s1, s4);

            Console.WriteLine("D");

            string s5 = "かるぼ" + "なら";

            CheckString(s1, s5);

            Console.WriteLine("E");

            CheckString(s1, StringCheck2.Class1.s);

        }

 

        private static void CheckString(string s1, string s2)

        {

            Console.WriteLine((Object)s1 == (Object)s2);

            Console.WriteLine(((Object)s1).Equals((Object)s2));

            Console.WriteLine(s1 == s2);

        }

    }

}

 

同じソリューションで別のプロジェクトに以下のプログラムがあります。

namespace StringCheck2

{

    public class Class1

    {

        public static string s = "かるぼなら";

    }

}

 

答えはこんな風にお願いします。

A

False

False

False

B

True

True

True

 :

 :

E

True

True

True

 

絶対実行しないで直感でお願いします。

投稿日時 : 2007年10月9日 23:46

コメントを追加

# re: stringクイズ 2007/10/09 23:52 えムナウ

どうしてそう考えたのかも書いてくださいね。

# re: stringクイズ 2007/10/10 0:00 えムナウ

すべての文字列は「かるぼなら」になります。
それらが等しいかどうかのチェックをしています。
StringCheck2のプロジュクトはクラスライブラリでStringCheckと別のDLLになります。
StringCheck.exe と StringCheck2.dll です。

# re: stringクイズ 2007/10/10 0:31 えムナウ

私は Visual Studio 2005 で確認しました。

# re: stringクイズ 2007/10/10 0:40 よもやま

A
True
False
True
B
True
False
True
C
True
False
True
D
True
False
True
E
True
False
True

>(Object)s1 == (Object)s2
同じ型をObject型キャストしてるだけだから。
>(((Object)s1).Equals((Object)s2));
s1の実態がs2と同じかどうかを判定している為
CheckString(s1,s1)であればtrueのはず
>s1 == s2
文字列比較が行われて、結果同一であるため。

#Javaも同じような問題あったような気がします。

# re: stringクイズ 2007/10/10 0:48 刈歩 菜良

やっべー!
わたしが答えない訳にはいかなーい!
でもわかんねー!
(>_<)

(Object)s1 == (Object)s2

((Object)s1).Equals((Object)s2)
って、一緒だと思ってたんですが... (~_~;)
ま、いいや、一緒ってことで私の直感を書いちゃいます。
A.
False
False
True
理由:
StringBuilderで作成される文字列データが文字リテラルな扱いがされるわけないと思うから。

B.
False
False
True
理由:
A.と同じで、動的に作られた"かるぼなら"が文字リテラルと(以下略
C.
True
True
True
理由:
どっちも文字リテラルだから、同じ文字列は同じ場所。
D.
False
False
True
理由:
これ実はびみょー。もしかして、最適化レベルで答え変わりません?
コンパイラが賢ければ、全部True。なぜなら、"かるぼ" + "なら"をひとつのリテラル"かるぼなら"として扱ってくれる。
そうぢゃなきゃ、3つめだけTrue。
E.
False
False
True
理由:
リテラルは、アセンブリ毎にスタティックな領域に取られるものなので、アセンブリが違えば領域は別個に取られるから。

全て勢いで書いちゃいました。
# と、今のうち言い訳しとこっと。(^・^)
# 怖くて実機確認できへん。(>_<)

# re: stringクイズ 2007/10/10 0:51 なちゃ

A
False
True
True
B
False …ひょっとすると微妙かな…
True
True
C
True
True
True
D
True
True
True
E
True
True
True

# re: stringクイズ 2007/10/10 0:59 なちゃ

あっと理由もですか…
理由も書くとおそらく答え書くのに近くなっちゃいそうな…

# re: stringクイズ 2007/10/10 1:09 Streetw☆

(Object)s1 == (Object)s2はReferenceEqualsですね。文字列インターンの話。
((Object)s1).Equalsって自信ありません。String.Equalsとして考えました。
s1 == s2は普通の文字列内容の比較。たしかJavaは違うってわんくまさんのブログで見たような...

A
false
true
true
B
true
true
true
C
true
true
true
D
true
true
true
E
false
true
true
#どきどき

# re: stringクイズ 2007/10/10 1:12 えムナウ

>かるぼさん。
>これ実はびみょー。もしかして、最適化レベルで答え変わりません?
デフォルトDebug Buildですよ。

>なちゃさん。
>理由も書くとおそらく答え書くのに近くなっちゃいそうな…
そう思うのならそれもありです。

# re: stringクイズ 2007/10/10 1:46 刈歩 菜良

> デフォルトDebug Buildですよ。
ぢゃ、答えそのままで3つめだけTrueにしときます。
# みんなとぜんぜん答えが違っていてへこんできたのは内緒。('_')

# 恥は書き捨て。勉強のモト 2007/10/10 2:45 Chuki

A
false →違うオブジェクトだから
true →StringクラスのEqualsで値を比較してるから
true →StringクラスのEqualsで値を比較してるから

B
false →動的な演算だから別のオブジェクトが作られた
true →StringクラスのEqualsで値を比較してるから
true →StringクラスのEqualsで値を比較してるから

C
true →同じオブジェクトだから(同じリテラルだから)
true →StringクラスのEqualsで値を比較してるから
true →StringクラスのEqualsで値を比較してるから
D
true →同じオブジェクトだから(コンパイル時にくっつけて解釈されるから)
true →StringクラスのEqualsで値を比較してるから
true →StringクラスのEqualsで値を比較してるから
E
true →DLLにしたら同じAppDomainに入るから
true →StringクラスのEqualsで値を比較してるから
true →StringクラスのEqualsで値を比較してるから

うーん、実行してみたい^^;

# re: stringクイズ 2007/10/10 4:21 渋木宏明(ひどり)

string は「特別なふるまい」をすることに注意、ですね。


# re: stringクイズ 2007/10/10 7:25 黒龍

A
false(オブジェクトが別)
true
true

B
false(オブジェクトが別)
true
true

C
false(最適化で変わりそうです)
true
true

D
false(最適化で変わりそうです)
true
true

E
false
true(staticなのはsだから)
true(同上)

む、難しい・・・

# re: stringクイズ 2007/10/10 9:59 R・田中一郎

A
False
True
True

片方は、StringBuilderのオブジェクトだから違うってことですね。
後は値が一緒なので一緒です。

B
False (なちゃさんと同じく微妙)
True
True

微妙と書いたのは、渋木さんの言うところの文字列は特別な処理をするから・・・という特別な処理の対象になるのかどうかという点です。
文字列連結した結果が、対象になるかどうかは試してみないとわかりません。
特別な処理について書くと、クイズにならなそうなので詳細は省略します。

C
True
True
True

これは特別な処理の対象になりますよね。

D
True
True
True

C と同じ理由です。

E
True
True
True

C と同じ理由です。

# re: stringクイズ 2007/10/10 10:20 Chuki

誘惑に駆られて実行しちゃったorz
あぁ、以後参加できんorz

ということで、解説をおとなしく待ってますm(_ _)m

# re: stringクイズ 2007/10/10 13:31 Hirotow

A
T
T
T
B
T
T
T
C
T
T
T
D
F
F
T

理由:
・Object.Operator==はObject.Equallsと等価。
・すべて値は"かるぼなら"のためString.Operator==がFalseを返すことはありえない。
・アセンブリが違うとストリングプールも異なる。

# stringクイズ解答編 2007/10/10 15:57 えムナウ Blog

stringクイズ解答編

# re: stringクイズ 2007/10/10 16:20 えムナウ

理由の私が用意したもの。

Object の 「==」は ReferenceEquals です。
string の 「==」は 「インスタンスに含まれているデータを変更できない」 ので Equals です。
したがって、CheckString の 一つ目は ReferenceEquals 二つ目三つ目は Equals を実行しています。

リテラル文字列は、インターン プール(リテラル文字列プール)に参照がおかれます。
動的に生成された文字列は、インターン プールに参照がおかれません。
EXE ファイルや DLL ファイルをロードする時にインターン プールの更新も行われます。

A・Bは動的に生成された文字列で、インターン プールを検索しませんから、リテラル文字列と同じ参照にはなりません。
C・D・Eはリテラル文字列でインターン プールに参照がおかれていますので、同じ参照値を持っています。
A・B・C・D・Eとも値は「かるぼなら」ですので値は一緒です。

解答

A
False
True
True
B
False
True
True
C
True
True
True
D
True
True
True
E
True
True
True

# re: 空の文字列 2008/04/21 15:59 R.Tanaka.Ichiro's Blog

re: 空の文字列

タイトル
名前
URL
コメント