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

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

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

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

Q&A

解決済

2回答

3905閲覧

引数ありのコンストラクタ

chintao1224

総合スコア155

C#

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

0グッド

0クリップ

投稿2018/12/08 06:08

C#を基本から勉強しています。
コンストラクタというのがありますが、そもそも引数ありのコンストラクタってあるのでしょうか?
ある場合、Cのような考え方になるのでしょうか?
Cは実行時に引数を与える場合があると思います。
C#でもそのような動き方になるのでしょうか?
C#実行時に引数を与えて実行しなければいけないみたいな。。。
詳しい方教えてください。
お願いします。

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

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

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

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

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

Zuishin

2018/12/08 07:14

もしかしてオブジェクト指向がいやで、コンストラクタを関数のように使ってすべてのプログラムを組もうと思っていますか?
chintao1224

2018/12/08 08:13

いえ、そんなつもりはありません。ただ引数がある場合のコンストラクタのことを知りたかっただけです。
ozwk

2018/12/09 01:36

コンストラクタをなんだと思ってます?何かそこから話が通じてない気がするんですが
Gurz1019_MP

2018/12/09 06:45

”実行時に引数を与える”というのは、コマンドライン引数のことをおっしゃっていますか?
guest

回答2

0

msdn ライブラリを見てください、ひとつのクラスのコンストラクターにも多数のオーバーロードがあるのが分かります。当然需要があるからです。

【追伸】

具体例を示した方がよさそうですので、SQL Server にアクセスするときに使う SqlConnection, SqlCommand, SqlParameter クラスのコンストラクタで、引数有りと引数無しの場合のサンプルを書いておきます。

どちらがスマート&可読性が高いかと言えば前者ではないでしょうか?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { string connString = @"Data Source=(local)\sqlexpress;Initial Catalog=NORTHWIND;Integrated Security=True"; string query = "SELECT [ProductID], [ProductName] FROM [Products] WHERE [CategoryID]=@ID"; // コンストラクタ引数有り using (SqlConnection connection = new SqlConnection(connString)) { using (SqlCommand command = new SqlCommand(query, connection)) { command.Parameters.Add(new SqlParameter("@ID", SqlDbType.Int)); // これ以下は同じ command.Parameters["@ID"].Value = 1; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine($"ID: {reader.GetInt32(0)}, Name: {reader.GetString(1)}"); } } } } // コンストラクタ引数無し using (SqlConnection connection = new SqlConnection()) { connection.ConnectionString = connString; using (SqlCommand command = new SqlCommand()) { command.CommandText = query; command.Connection = connection; SqlParameter param = new SqlParameter(); param.ParameterName = "@ID"; param.SqlDbType = SqlDbType.Int; command.Parameters.Add(param); // これ以下は同じ command.Parameters["@ID"].Value = 1; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine($"ID: {reader.GetInt32(0)}, Name: {reader.GetString(1)}"); } } } } } } }

その他、例えば(あくまで例えばですが)、Windows Forms アプリで Form1 で初期化してDB からデータを Fill した DataTable オブジェクトへの参照を Form2 に渡す場合など、Form2(DataTable table) というコンストラクタを定義して、Form2 を初期化するときに渡すということも可能です。

投稿2018/12/08 07:23

編集2018/12/08 12:48
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

C言語で構造体を初期化する関数を作ったことがあるなら、それを言語仕様として定義したのがコンストラクタだと思って下さい。
構造体の中に初期化関数も書けるみたいな感じです。
引数の考え方は同じです。

ただしコンストラクタだけ覚えてもC#の事はなにもわからないと思いますので、入門書なり入門Webページなりを呼んだほうがいいです。

追記:後から思いついたのですが、引数有のコンストラクタと引数なしのコンストラクタが同じクラスに書けることを言っているのでしょうか?
それはC言語にはないオーバーロードというものです。
呼ぶときの引数によって、呼ばれるコンストラクタ(メソッドも)を区別できるのです。

投稿2018/12/08 06:49

編集2018/12/08 07:02
hihijiji

総合スコア4150

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

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

chintao1224

2018/12/08 07:27

すみません、もう少し。 ということは、引数ありのコンストラクタがある場合、実行時に引数をあてなければプログラム自体実行できないのか、コンストラクタだけスルーされてプログラムが実行されるのか、どちらになるのでしょうか?
hihijiji

2018/12/08 07:35

引数なしのコンストラクタがあれば引数なしでもコンパイルは通りますが、実行できるかどうかは書いたプログラム次第です。 引数有りのコンストラクタしかない場合は、引数を与えないとコンパイルできません。
chintao1224

2018/12/08 07:39

ちなみにプログラムに必ずコンストラクタは必要なのでしょうか?
hihijiji

2018/12/08 07:41

必ず必要です。 省略した場合はデフォルトのコンストラクタが適用されます。
Zuishin

2018/12/08 07:57

静的クラスをお忘れではないですか?
chintao1224

2018/12/08 08:02

すみません、静的クラスってなんでしょうか?
hihijiji

2018/12/08 08:12

静的クラスには静的コンストラクタが(必ず)あるとおもいますよ。CLIを確認したわけではありませんが…
Zuishin

2018/12/08 08:31

var i = typeof(Program).GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).Count(); Console.WriteLine(i); これで静的コンストラクタの数を確認できますが、定義しない場合には 0 になりました。 BindingFlags.Static を BindingFlags.Instance に変えた場合は 1 になります。 これはデフォルトのインスタンスコンストラクタの数ですね。
Zuishin

2018/12/08 08:33

また Program クラスを静的クラスに変更した場合にはインスタンスコンストラクタも 0 になります。
hihijiji

2018/12/08 09:06 編集

確認有難うございます。 となると、静的コンストラクタを書かない静的クラスのメンバの初期化はクラスの外でやっていることになりますね。 謎が増えてしまった。
tamoto

2018/12/08 09:07

横からですが。 staticコンストラクタはオブジェクトを作らないので、空のstaticコンストラクタとstaticコンストラクタ無しが概念的に等しくなるため実装が省略されているのでしょう。 ちなみにF#からは本当にコンストラクタを持たないクラスというヘンなものも作れてしまうので、デフォルトコンストラクタがあるというのもC#に限った話なんですよね。
Zuishin

2018/12/08 09:39

次のコードを実行するとこのように表示されます。 Hello 作成中 コンストラクタ Hello using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { Console.WriteLine(Static.Hello); Console.ReadKey(); } } static class Static { static Static() { Console.WriteLine("コンストラクタ"); } public static string Hello = SayHello(); private static string SayHello() { Console.WriteLine("Hello 作成中"); return "Hello"; } } }
hihijiji

2018/12/08 10:02

静的クラスはクラスの一形態というより、似ているけど根本的には違うものなんですねぇ
Zuishin

2018/12/08 10:08

いえ、静的クラスが違うというより、インスタンスとクラスが違うと言うほうが正確だと思います。 static class Static を class Static に変えても同じ順に表示されます。 インスタンスコンストラクタはインスタンスを作成するのでインスタンスメンバーはそれより前に初期化することはできませんが、静的メンバーはインスタンスを必要としないので静的コンストラクタより前に初期化することができます。 静的コンストラクタはコンストラクタではなく自動的に実行される初期化用メソッドと考えた方がいいと思います。
退会済みユーザー

退会済みユーザー

2018/12/09 01:09

質問者さんへ> > すみません、静的クラスってなんでしょうか? ググるなどして調べてみましたか? c# static class をキーワードにググると以下の記事が一番最初にヒットします。まずはそれを読んでみて、分からなければ聞くというようにしましょう。 静的クラスと静的クラス メンバー (C# プログラミング ガイド) https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members
chintao1224

2018/12/09 06:17

newを使ってインスタンスを作る必要のないクラスってことは分かったのですが。なんのメリットがあるのでしょうか?クラスって実体のない箱のようなものですよね。それを使ったメソッドなんて、そこがイマイチピンときません。
退会済みユーザー

退会済みユーザー

2018/12/09 06:33

> newを使ってインスタンスを作る必要のないクラスってことは分かったのですが。なんのメリットがあるのでしょうか? 紹介した記事の、静的クラス System.Math の例に、「Math クラスの特定のインスタンスに固有のデータを格納または取得する必要はありません」と書いてあって、以下のコード例があるのを読みましたか?  double dub = -3.14; Console.WriteLine(Math.Abs(dub)); もし、Math がインスタンスクラスだと、どうしなければいけないか分かります? -3.14 の絶対値を得るという目的のためだけに、わざわざ Math のインスタンスを生成する必要はないと思いませんか?
chintao1224

2018/12/09 07:19

確かにそうですね。「クラスって実体のない箱のようなものですよね。それを使ったメソッドなんて、そこがイマイチピンときません。」は内部的にインスタンスが作られているということでしょうか?VB6をずっとやってきた僕にとって、静的クラスはインスタンス作らなくて良いですし、使いやすいような気がしました。多用しても大丈夫なものなのでしょうか?
tamoto

2018/12/09 07:49

静的クラスはオブジェクト指向の概念とやや対立する部分があるため、その違和感はおかしくないです。 静的クラスは要するに「インスタンスを生成することが不可能なクラス定義」というもので、インスタンスを生成しないでも意味がある定義しか置けない、という制約付きのクラスでしかないです。 便利ではありますが、オブジェクト指向の要素の一つとして扱うのが難しくなるため、多用すると面倒なことになる場合があり得ます。 Mathクラスのようなユーティリティや、extensionを定義したいようなシーンで採用するのが良いです。
退会済みユーザー

退会済みユーザー

2018/12/09 08:46

> 多用しても大丈夫なものなのでしょうか? 少なくとも C# で(VB.NET でも)、.NET アプリを作るなら 100% 絶対に大丈夫ではないと思います。はっきり言わせてもらえれば見当ハズレと思えます。私の回答例も見てください。勉強を進めてください。そうすれば自然と分かるのではないかと思います。
chintao1224

2018/12/09 14:38

了解しました。勉強になりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問