string str = "abc";
のように宣言と代入したときにできるstrは、"変数"なのでしょうか、それとも"オブジェクト"なのでしょうか?
構文から考えると、intやdoubleのように変数であると考えられます。
しかし、変数ならば、str.Length
のようにプロパティを参照したり、Replace()メソッドを使えたりといったように、あたかもオブジェクトであるかのように扱うことはできないはずです。
以上のことから、stringは、変数のような構文で宣言することができるが、コンパイラによって自動的にインスタンス化されるなどしており、その実体はオブジェクトであると考えました。
そこで疑問に思ったのですが、変数のように宣言するのではなく、newを使ってインスタンス化することはできないのでしょうか?
(変数のように宣言すればいいことはわかっていますが、言語仕様上、明示的にインスタンス化することもできるのではないかと思いました)
回答よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
訂正:「オブジェクトか?」という点の記述が不適切でした。自分の回答は「box化がなくてもObjectの派生クラスとして実現されているか」という意味合いで話していますが、C#の言語仕様上box化されるかどうかは内部的な話であってChironianさんがおっしゃるように仕様上全てobjectの派生である」ということになります。失礼しました。
下の回答でオブジェクトという用語を使っている箇所は参照型という意味合いで使っています。文章を書き換えると質問者さんの「オブジェクト」という用語とかけはなれた説明になってしまいますね。
すみませんが以下は元の回答のままとさせてください。
用語の使い方に若干混乱が...
なんていっておきながら自分の方がObjectの説明を間違えてしまいました。大変失礼しました。
以下、元の回答
「変数」「オブジェクト」「インスタンス化」の用語の使い方に若干混乱が見られます。おそらくは「リテラル」「値」という用語を正しく使えることができればより意味の通る文章にできると思います。
それはともかく・・・
string str = "abc";
のように宣言と代入したときにできるstrは、"変数"なのでしょうか、それとも"オブジェクト"なのでしょうか?
オブジェクトです。型がstringと宣言されているので変数strにはnullおよびstringクラスのインスタンス以外の「値」である可能性はありません。なお、これは変数宣言をしているからそうなるのではなく代入文の右辺の"abc"
という記述そのものの意味が「stringクラスのオブジェクト」になります。
(質問文を文字通り読むと「変数です」という答えもあり得ますが、多分質問者さんは「どんな値になるか」を疑問に思っておられると思ったのでこういう回答にしています。)
構文から考えると、intやdoubleのように変数であると考えられます。
この文章から用語の理解に間違いがあるように感じます。「変数」は「値」を入れる場所です。質問者さんが問題にしていると思えるのは「オブジェクトなのか変数なのか」ではなく「どのような値なのか」というべきだと思います。
"abc"はオブジェクトなのですがそれは少し詳しくいえば「string型の値」であり、「string型のような参照型の値のことを一般にオブジェクトクトと呼ぶ」のでオブジェクトクトという言い方もするだけです。
1や1.1はオブジェクトとは呼びませんが、それらは「intやdoubleなどの値型の値」と呼びます。
「"abc"がオブジェクトで1や1.1がオブジェクトでない」のは「stringが参照型で、int/doubleが値型」であり参照型のインスタンスのことをオブジェクトと呼ぶという違いに過ぎません。
そこで疑問に思ったのですが、変数のように宣言するのではなく、newを使ってインスタンス化することはできないのでしょうか?
できます。・・・が、やはりこの文章も次のように言うべきです。「オブジェクトをリテラルとして表現するのではなく、明示的にnewを使ってインスタンス生成するようなことができるか?」
この質問が「コンパイラーがどこかに用意している謎のオブジェクト"abc"としてではなく、自分で明示的に同じ内容のインスタンスを生成する記述ができるか」という疑問だったと解釈すると、次のようにすれば可能です。
C#
1//--- stringリテラルを一切使わずに"abc"を生成する書き方 --- 2 3// (1) 4char[] chars = new char[3]; 5chars[0] = 'a'; 6chars[1] = 'b'; 7chars[2] = 'c'; 8string str = new string(chars); 9 10// (2) 11char[] chars = { 'a', 'b', 'c' }; 12string str = new string(chars); 13 14// (3) 15string str = new string(new char[] { 'a', 'b', 'c' }); 16 17//--- stringリテラルを使う --- 18 19// (4) 20string str = "abc";
どれも効率上の違いがあるだけでstrに設定されるstring値はいずれも同等になります。
投稿2017/06/05 03:58
編集2017/06/05 05:44総合スコア18394
0
まず変数には「値型」と「参照型」があって、プログラミングの際はどちらなのかを意識する必要がありますが、そのあたりの理解は十分でしょうか? もし理解が十分でなければ、まずは以下の記事を読むなりググって調べるなどして、「値型」と「参照型」の違いを理解してください。その上でないと話が通じにくいです。
2-3 値型と参照型
https://msdn.microsoft.com/ja-jp/library/cc406735.aspx
値型と参照型の区別と違い
http://dobon.net/vb/dotnet/beginner/valuereference.html
で、String の話ですが・・・
String は参照型なのですが、「文字列オブジェクトの不変性」と「インターンプール」という特殊性に注意が必要です。
「文字列オブジェクトの不変性」については以下の記事を見てください。
文字列 (C# プログラミング ガイド)
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/strings/index
要点を抜粋すると "文字列オブジェクトは変更不可です。つまり、作成した文字列オブジェクトは変更できません。 文字列を変更するように見える String メソッドと C# 演算子はすべて、実際には新しい文字列オブジェクトで結果を返します" ということです。
「インターンプール」によってどういうことが起こるかは、例えば以下の記事の「使用例」のコードで (object)a == (object)c が true になるところを見てください。
== 演算子 (C# リファレンス)
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/equality-comparison-operator
投稿2017/06/05 03:22
編集2017/06/05 03:27退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
こんにちは。
「オブジェクト」と「変数」が同居できないイメージを持たれているようですが、同居できますよ。といいますか、C#の変数は全てオブジェクトの一種です。
C# の型とメンバーや型 (C# プログラミング ガイド)が網羅的に説明してます。
しかし、こうしてみるとC#のデータ型ってかなり難しいですね。
C++より複雑なことにちょっとびっくりしてます。
投稿2017/06/05 03:14
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
引用テキストstrは、"変数"なのでしょうか、それとも"オブジェクト"なのでしょうか?
String"abc"インスタンス(オブジェクト)を格納した、String型の変数。
よって、変数。
変数はあくまでもオブジェクトを格納するもの。C#の場合は、変数に型づけができるので
変数定義時にstringのオブジェクトを入れる変数を定義する。定義と同時にString"abc"
のインスタンス(オブジェクト)を代入する。
構文から考えると、intやdoubleのように変数であると考えられます。
s.t.さんが説明されているので割愛。値型と参照型の違いならまた別です。
しかし、変数ならば、str.Lengthのようにプロパティを参照したり、Replace()メソッドを使えたりといったように、あたかもオブジェクトであるかのように扱うことはできないはずです。
C#
1string str = "abc"; 2// strには string のインスタンス(オブジェクト)が格納されている 3// strの中身は stringのインスタンスが格納された後なので、Lengthプロパティ参照できる 4// "abc".Length と等価 5int size = str.Length; 6 7string nullStr; 8 9// nullStrには string のインスタンス(オブジェクト)が格納されて 10// nullStrは定義されただけでデフォルト値stringの場合はNull 11// 以下はエラー 12int nullStrSize =nullStr.Length; 13
そこで疑問に思ったのですが、変数のように宣言するのではなく、newを使ってインスタンス化することはできないのでしょうか?
できる。あとstringの中身はcharの配列。なので、以下みたいにできる。
ただ基本的にコンパイラが自動的にその辺りやってくれる(厳密には言語仕様だ)からプログラムとして書けるだけ。
C#
1 string s2 = new string(new char[] { 'H', 'e', 'l', 'l', 'o' });
投稿2017/06/05 02:35
総合スコア1013
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/06/05 04:05
2017/06/05 04:15 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/06/05 05:00
2017/06/05 05:21 編集
退会済みユーザー
2017/06/05 05:23
2017/06/05 05:37