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

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

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

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

Q&A

解決済

4回答

890閲覧

C#のエントリーポイントの位置について

YasAct

総合スコア1

C#

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

0グッド

0クリップ

投稿2021/06/17 04:12

編集2021/06/21 09:08

前提・実現したいこと

現在C#の勉強を行っております。具体的には「独習C#」を読んでおるところです。
Sample1のように、エントリーポイントの中で自身(Mainメソッド)を含むクラスのインスタンスを行ってよい理由がどうしてもしっくりと理解できません。
再帰的に自分(Mainメソッド)を呼び出せるように見えてしまって、どうしても違和感が拭えません。

たとえばSample2のように、もう一つクラス(Program)を作って、そちらでMainメソッドを持ち、インスタンス化するような書き方であれば、自分の中では納得できるのですが・・・
Sample1のように書いて良い理由と、そのメリット等が知りたいです。

該当のソースコード

Sample1

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6 7namespace Sample1 8{ 9 class Sample1 10 { 11 public string data = "フィールド"; 12 13 public string show() 14 { 15 string data = "ローカル"; 16 return data; 17 } 18 static void Main(string[] args) 19 { 20 var s = new Sample1(); 21 Console.WriteLine(s.show()); 22 Console.WriteLine(s.data); 23  } 24 } 25}

Sample2

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6 7namespace Sample2 8{ 9 class Sample2 10 { 11 public string data = "フィールド"; 12 13 public string show() 14 { 15 string data = "ローカル"; 16 return data; 17 } 18 } 19 class Program 20 { 21 static void Main(string[] args) 22 { 23 var s = new Sample2(); 24 Console.WriteLine(s.show()); 25 Console.WriteLine(s.data); 26 } 27 } 28 29}

210621追記

https://www.javadrive.jp/start/about/index4.html
にjavaの文脈ですが説明を見つけ、とりあえずスッキリしましたので、自分用のメモとして追記します。

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

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

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

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

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

guest

回答4

0

再帰的に自分(Mainメソッド)を呼び出せるように見えてしまって、どうしても違和感が拭えません。

今回の質問のコードでは別に再帰呼び出しはしていませんが、
Main()を再帰呼び出ししても別に問題ありません。
なので違和感の前提がそもそも間違っています

C#

1public class Hello{ 2 public static void Main(string[] args){ 3 if(args.Length == 0){ 4 System.Console.WriteLine("Hello C#"); 5 Main(new string[]{"hoge"}); 6 return; 7 } 8 System.Console.WriteLine("Hello C#!!!"); 9 } 10} 11

投稿2021/06/17 04:45

編集2021/06/17 05:00
ozwk

総合スコア13528

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

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

YasAct

2021/06/17 08:33

ありがとうございます。 頂いたコードも試してみました。 さらに Main(new string[] {}); として、抜け出せなくなることも確認してみました笑(StackOverFlowしました) ところで、少し抽象的になりますが、違和感の原因を考えてみたところ、 クラスのイメージを「設計図」として捉えていたことに気が付きました。 すなわち、 エントリーポイントのMainメソッドの視点に立った時、 自分でなにか作ろう(インスタンス化)としたとき、 その設計図(クラス)を見てみたら自分そのものが書かれていた。という違和感です。 クラス=設計図として説明することが、完全ではないということはどこかで読んでいたのですが、その実例かもしれません。 また、そもそもstatic メソッド(正しくはstatic修飾子)の定義も理解できていなかったため、思い違いをしていたように思います。 「インスタンス化されたオブジェクトにはstaticメソッドは入っていない」というイメージで腑に落ちそうです。 確かに、再帰的な構造にすることはあり得ると理解できますし、その視点から見ると納得できます。 が、上記のアナロジー視点に縛られてしまって違和感を感じたのかもしれません。
guest

0

ベストアンサー

Sample1のように、エントリーポイントの中で自身(Mainメソッド)を含むクラスのインスタンスを行ってよい理由がどうしてもしっくりと理解できません。
再帰的に自分(Mainメソッド)を呼び出せるように見えてしまって、どうしても違和感が拭えません。

すごくよくわかります。わたしも最初、困惑したのを覚えています。
正直慣れな気もしないのでもないので、詳しくはおそらく独習C#を熟読していけばいつのまにか理解できるんじゃないかと思います。

それだと回答としてあんまりなので、すこし回答しておくと、そもそもメソッドが再帰になるパターンを考えてみると、

cs

1class A { 2 void a(){ 3 a( 4 } 5}

とa()の定義中にa()が呼び出されていて、自分自身と同じメソッドだからこそ再帰になりえるわけです。

cs

1class Sample { 2 static void Main(){ 3 new Sample(); 4 } 5}

という形です。つまりMain()というメソッドの定義中に、Sample()というコンストラクタ(これも特殊なメソッドです)が呼び出されていて、つまり異なるメソッドを呼び出しているからこそ、再帰にならないわけです。

注意しておきたいのが、Sample()の定義は省略されているということです。つまりSample()はSample()と別の場所で定義されています。つまりこういうことです。

cs

1class Sample { 2 public Sample(){ 3 } 4 static void Main(){ 5 new Sample(); 6 } 7}

このことからも、Main()とSample()が異なるメソッドだということが分かります。
また、class Sample{ }と、public Sample(){ }自体も混同してる可能性があるので、これらも確り区別して考えてください。

そのメリット等が知りたいです。

ぶっちゃけ、短く書ける以外に特に無いように思います。

投稿2021/06/17 04:57

編集2021/06/17 05:32
nobkz

総合スコア320

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

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

YasAct

2021/06/17 08:42

ありがとうございます。 別のコメントでも書いたのですが、 クラス=設計図とするアナロジーで考えると、どうしても作ろうとしたものの設計図に自分が入っているという構造に違和感があったのですが、そもそもstaticの意味を理解していなかったので、より違和感が強くなっていたように思います。 >正直慣れな気もしないのでもないので、詳しくはおそらく独習C#を熟読していけばいつのまにか理解できるんじゃないかと思います。 >ぶっちゃけ、短く書ける以外に特に無いように思います。 といただいたことがとても心強く、いずれにしろ、機能上の大きな差異が無いのであれば、慣れるまではSample2の様に脳内で変換して読み進めたり、コードを書いてみようかと思います。
guest

0

質問の例を見る限り勘違いをされているように思います。

エントリーポイントはアプリケーションが起動する時に呼ばれるものです。

C#

1var s = new Sample1();

とSample1クラスのインスタンスを作成してもMainメソッドが自動で呼ばれるわけではありません。

投稿2021/06/17 04:22

YAmaGNZ

総合スコア10258

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

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

YasAct

2021/06/17 04:38

ありがとうございます。 >エントリーポイントはアプリケーションが起動する時に呼ばれるものです。 ということは理解していたつもりで、 アプリケーションが起動した際に自動的にMainメソッドが自動的に呼ばれ、 そこで、Main自身を含むクラスをインスタンス化しているという構造に違和感を覚えてしまっておるのです・・・
neconekocat

2021/06/17 04:47

staticメソッドから自身のインスタンスを作成するパターンは普通にありますよ。あまり使いませんけど。
YAmaGNZ

2021/06/17 04:59

自分自身のインスタンスを作成しても問題はありませんし、再帰的に呼ぶことにも問題はありません。 ただ、再帰的に呼び出す際にちゃんと抜け出せるようにしないといけません。 そのあたりは普通の再起呼び出しと同じです。
fana

2021/06/17 05:00

Main には > アプリケーションが起動した際に自動的にMainメソッドが自動的に呼ばれ という特別なルールが1個あるだけで, それ以降については Main も他のメソッドも扱いとしては同じ(※)というだけですね. (※)どうやらMainの引数に渡せるものに関しては制限があるっぽいが
guest

0

sample1とsample2は特に大きな違いはないと思います。
しっくりいく方で書けば良いと思います。
ただし、sample1の方がクラスを1つにまとめることができる点が違いです。
この例のようなサンプルでは、ソース量も少ないので、
わざわざクラスを分ける必要性がないと思うのため、
sample1で良いとは思います。

投稿2021/06/17 04:18

kikukiku

総合スコア514

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

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

YasAct

2021/06/17 08:46

ありがとうございます。 他の方もおっしゃっている様に、機能上の差異がなければひとまずSample2の様に変換して理解して進めてみようかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問