2009-10-04 8 views
7

タイトルのとおりです。 Related to this question.なぜC#はcharの加算演算を定義していませんか?

なぜ次のコードは機能しませんか?論理的には合理的だと思われる。 - これらの値を加算し、その後、> int型の変換コンパイラは、暗黙の文字を使用している:我々はここで何が起こっているかを推測することができます上記のリンク質問から

string foo = 'a' + 'b'; // Fails with an invalid int -> string conversion 

、。これは、char sのために定義された加算演算があってはならないと信じさせてくれます!これは本当ですか、もしそうなら、なぜそこにはありませんか?

編集:一般的なコンセンサスは、定義されると期待されるほど大きく定義されていないということです。

+11

2つの文字を文字列に変換する追加を意味するのは、そのことをコンパイラが望んでいないからです。確かに、それはデフォルトの振る舞いとして追加されている可能性がありますが、他の人がcharを実際に整数として追加する方が好きかもしれません...だからここでは最初のcharから文字列をインスタンス化し、すべての誤解を避ける。 – RedGlyph

+0

@redglyph:それが答えだったら私はそれをupvoteしたい。 –

答えて

15

まず、あなたの演繹的プロセスについての言葉。あなたの控除 - そのcharはintに変換されるので、charに定義された加算演算子はありません。しかし、私は控除プロセスが不要であったことに注意します。すべての組み込み演算子を明確に記述している、仕様の7.7.4節を読んでおくとよいでしょう。簡単に言えば、int + int、uint + uint、long + long、ulong + ulong、float + float、double + double、decimal + decimal、enum-and-underlying型、デリゲートコンビネーション、string + string、string + objectオブジェクト+文字列。 (そして、もちろん、値型を含む型のnullからnullへの持ち上げが可能です。)そうですが、charをとる加算演算子はありません。

第2に、あなたの「なぜですか?」と答えてください。 - 文字は少し奇妙です。それらの記憶は短い整数の記憶であるが、それらの意味は文字列内の文字の意味である。だから、charはその整数型として扱われるべきか、あるいは短い文字列として扱われるべきですか?言語設計者はこの場合、Cのような初期の言語の主導に従うことを決め、文字列に関係しない数学を行うときには整数のような文字を扱います。短い文字列のように扱う場合は、文字を文字列に変換する方法はいくつもあります。別の答えが示唆するように、空の文字列を追加すると、コンパイラに「この操作は文字の整数値ではなく文字列にある」ことが明確に伝えられます。

+2

空の文字列に追加するのは信じられないほど醜いスタイルです。 String.Concatは行く方法です。 –

3

質問には"なぜ"という単語に焦点を当てるべきだと思っています。 C#では、2つの文字を追加する動作は、「連結」ではなく「Unicode値を追加」を意味するように定義されています。これは、文字列と文字が、過去の人生とはるかに異なる整数(例えば、Cプログラミング言語)であることを考えると、より合理的に「連結」を意味すると定義することができました。

'a'は文字定数です。伝統的に、文字定数は、少なくともCでは、整数を表す別の方法でした。この場合、整数( 'a' = 97、 'b' = 98など)のUnicode値。したがって、式 'a' + 'b'は、これらの2つのUnicode値を一緒に加算することを意味します。あなたが期待しているものを達成するために

、というよりも、すでに文字が整数の形ではなく、文字列とみなされ、言われているので、基本的にほかの操作は2つの数値を追加すると

String foo = "a" + "b"; // double quotes = single-character strings to concatenate 
+1

この場合ASCIIではありません。 C#では、CharsはUnicodeです。 –

+0

C#では、その点で事柄はより緊密です。特に、これは動作しません: 'char foo = 32;' –

+0

@James - 私に思い出させるためにありがとう。早いです。それに応じて更新された投稿。 –

3

を行います連結を実行する。 foo2はのために

string foo2 = 'a' + "" + 'b'; // Succeeds 
string foo3 = 'a'.ToString() + 'b'.ToString(); // Succeeds 
string foo4 = string.Concat('a', 'b'); // Succeeds 

:あなたはあなたの本来の意図に似たいくつかのいずれかを行うことができますまで、あなたの文字を「追加」してもらうために

string str = String.Format("{0}{1}", 'a', 'b'); 
1

:あなたはこのような文字列に2つの文字を取得することができます例では、空の文字列を削除して暗黙の文字を各文字の文字列変換に個別に強制することによって、コンパイラにヒントを与えます。

foo3の例では、各文字にToString呼び出しを使用して2つの文字列を追加することができます。

0

あなたは、文字列の加算演算子のオーバーロードを使用して、この試みることができる:

var result = "" + 'a' + 'b'; 

をしかし、それはあなたの文字列に変換 int型を与えるよう

var result = 'a' + 'b' + ""; // BAD !!!!! 

と混同しないようにしてくださいと「195」に等しい。

文字列をキックインするために、演算子+のオーバーロードがあり、これを達成するための最初の引数が必要です。

これはちょっと違うようですが、それはC#です - 無意味で無慈悲です! (実際には、(Char、Char)には演算子+オーバーロードがなく、CharはInt32にキャストしようとしています)。

string foo = String.Concat('a', 'b'); 

コンパイラはとにかく文字列に「+」演算子で何をするかでどちら:あなたが本当に探しているものを

7

はこれです。

これは、String.Format操作の約2倍の速さです。

関連する問題