質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Q&A

解決済

5回答

7209閲覧

C#のstring型はオブジェクトですか?

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

0グッド

2クリップ

投稿2017/06/05 02:06

編集2017/06/05 02:11

以前このような質問(https://teratail.com/questions/78985?sip=n0070000_019&uid=61045)をさせていただいたものです。回答を読んで、自分の疑問点が整理できたので改めて質問させていただきます。

string str = "abc";
のように宣言と代入したときにできるstrは、"変数"なのでしょうか、それとも"オブジェクト"なのでしょうか?

構文から考えると、intやdoubleのように変数であると考えられます。

しかし、変数ならば、str.Lengthのようにプロパティを参照したり、Replace()メソッドを使えたりといったように、あたかもオブジェクトであるかのように扱うことはできないはずです。

以上のことから、stringは、変数のような構文で宣言することができるが、コンパイラによって自動的にインスタンス化されるなどしており、その実体はオブジェクトであると考えました。

そこで疑問に思ったのですが、変数のように宣言するのではなく、newを使ってインスタンス化することはできないのでしょうか?
(変数のように宣言すればいいことはわかっていますが、言語仕様上、明示的にインスタンス化することもできるのではないかと思いました)

回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/05 05:00

私の知りたかったことを汲み取っていただきありがとうございます。ほとんど解決しました。 オブジェクトの種類について詳しく知りたいのですが、あるクラスをインスタンス化して生成したオブジェクト以外にも、int[]などの配列や、 "abc"などのリテラルもオブジェクトと言えるのでしょうか?また、これ以外にもあるのでしょうか?
KSwordOfHaste

2017/06/05 05:21 編集

オブジェクトは文脈によって微妙に意味がかわると思います。C#で「objectクラスのインスタンスなのか?」という表現なら明確ですが、カタカナで「オブジェクトか」と言われると若干迷います。自分ならstructは値型だけど、オブジェクトといってしまいそうです。質問者さんが知りたいことがobjectクラスのインスタンスかどうかという意味ならある型Tの変数xがあったとき(x is object)の結果を調べればそれが分かりますよ。網羅的に知りたいときはC#の解説(インターネットや書籍)で調べてみてください。 --- 失礼!間違えました。x is objectだとboxingされてしまうので、調べられません>< やはりC#の解説(インターネットや書籍)で調べることをお勧めします。
退会済みユーザー

退会済みユーザー

2017/06/05 05:23

isの存在は知ってましたが、 ` "abc" is object // True ` のように使うのですね。 おかげさまで理解が深まりました。ご指摘の通り、用語の定義を確認し直したいと思います。
KSwordOfHaste

2017/06/05 05:37

やば・・・回答におかしい点がありました。 intなどの値型をobject型でないという意図で話してしまいましたが、大きな間違いです。 Chironianさんがおっしゃるように、C#では全てobjectでした! 回答を訂正しておきます。
guest

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

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/05 04:17 編集

1つ目のリンク先に書いてある 「すべての型 (定義済み、ユーザー定義、参照型、および値型) が、直接または間接的に Object を継承します。」という文を読んで理解できました。string型はObjectを継承しているのですね!
guest

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

kanimaru

総合スコア1013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/05 04:05

詳しい説明ありがとうございます。 C#では、変数にオブジェクトを格納して、それに型(intやstringなど)を与えているということで間違いないでしょうか?
kanimaru

2017/06/05 04:15 編集

多分、色々混同されているかとおもいます。継承関係なども学ばれるべきかもですね。 > C#では、変数にオブジェクトを格納して、それに型(intやstringなど)を与えているということで間違いないでしょうか? 型が違う変数には、派生した型でもない限り型の異なれば代入できません。 ただ、例外が var で変数定義ですが、C#の場合は型推論によるものや 匿名型などがあるので、結構複雑ではあります・・。
guest

0

具体的にどのようにnewを使ってインスタンス化をするのでしょうか?
C#では文字列はstring型オブジェクトになります。
stringのコンストラクタがあるかどうかはわかりませんが、無駄になるかと思われます。

ToCharArray()などを使ってコンストラクタに入れてやればできるかもしれませんが、これも無駄かと思われます。

あと、C#にはボックス化というものがありますので、int型をオブジェクト型として参照したりすることも可能です。

投稿2017/06/05 02:28

s.t.

総合スコア2021

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問