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

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

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

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

3回答

2958閲覧

C#:staticメソッド内でstaticでない変数やstaticでないメソッドを使用できないのはなぜ?

zenobread

総合スコア44

C#

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

2クリップ

投稿2021/05/16 08:28

編集2021/05/16 08:40

##わからないこと

大前提として、「static修飾子をもつものはインスタンスが作れない」ことは理解しています

ですので

c#

1public static class A 2{ 3 public static int a;//OK 4 public int b;//NG 5 6 public static void AA()//OK 7 { 8 9 } 10 public void BB()//NG 11 { 12 13 } 14}

このようにclassにstaticがついていると、中のメンバーやメソッドにstaticを付けないといけないことはわかります。

問題は

C#

1 2public class A 3{ 4 public static int a; 5 public int b; 6 7 public static void AA()//OK 8 { 9 Debug.Log(a); 10 } 11 public static void AB()//NG??? 12 { 13 Debug.Log(b); 14 } 15 public static void AC()//OK 16 { 17 AA(); 18 } 19 public static void AD()//NG??? 20 { 21 BA(); 22 } 23 public void BA()//OK 24 { 25 Debug.Log(a); 26 } 27 public void BB()//OK 28 { 29 AA(); 30 } 31}

っこのABとADのように「静的でないクラスの中にあるstaticメソッド内で静的でないメソッドや変数を呼ぶとエラーを吐く」ことについて、
なぜこのような仕様になっているかが分からないです。
私の考えとしては、「staticな関数や変数をインスタンス化するわけではないからstaticメソッド内で何を参照しようが問題ないのでは」ということです。

よろしくお願いします

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

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

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

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

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

Zuishin

2021/05/16 08:32

dynamic クラスとかいう独自な用語を使うからわからないのでは?
zenobread

2021/05/16 08:36

ご質問ありがとうございます。 誤解を与えるような記述をしてしまい申し訳ありません。 dynamicクラスと書かせていただきましたが、静的ではないクラスの対義語として記述しております。 パッと調べてみてstaticではないものの呼び方が分からなかったため、staticの対義語を書いております そちらについて誤解を与えてしまわないよう、追記させていただきます。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2021/05/16 08:41 編集

(同時に指摘があったので削除)
zenobread

2021/05/16 08:43

お二方ありがとうございます。 dodox86様のご回答を確認する前に修正してしまいまして、冗長ですがdynamicとしていたところを「静的でない」と変換ました。 >少なくとも本質問でと問うていることはインスタンスメソッドやインスタンスフィールドについて、です。 dodox86様、インスタンスメソッドという名称はインスタンス化した関数のことをさすものであり、インスタンスのもとになった関数を呼ぶものではない、と考えているのですが間違いでしょうか。 間違いであればインスタンス元とインスタンス化したものを区別する際はどのように呼称されるのでしょうか。ご教授お願い致します。
dodox86

2021/05/16 09:03 編集

> インスタンスのもとになった関数を呼ぶものではない、と考えているのですが間違いでしょうか。 コメントの範疇を超えるような気がするので少しだけ気が引けるのですが、聞かれたので一応。 「インスタンスの元」と言う表現が分からないのですが、どういうものを指していますか。クラスの定義自体をイメージしていますか。 インスタンス化したメソッド(関数)というよりは、クラスをインスタンス化したときに使えるメソッドと言った方が良いかもです。インスタンスメソッドの中からは、そのクラスをnewでインスタンス化したときに初めて発生(?)するインスタンスフィールドにアクセスできますが、 staticメソッドはインスタンス化していない状態で呼びだせるものの、クラスのインスタンスフィールドへはアクセスできません。(インスタンス化していないので当たり前) メソッドに関してどういう呼称かというと、リファレンスでも「インスタンスメソッド(instance method)」と「スタティックメソッド(static method)」です。 https://docs.microsoft.com/en-us/dotnet/csharp/methods
zenobread

2021/05/16 09:26

ありがとうございます。はい、私としてはインスタンスの元=クラスの定義と考えておりました。 ご回答を拝見すると、クラス定義内のメソッドAと、そのクラスから生成されたインスタンスのメソッドA’があるとして、両者を区別するstaticやインスタンスみたいな故障はないのでしょうか。 ご懸念の通り質問からやや外れた内容かもしれないですが、後学のためお手数ですがご回答お願い致します。
dodox86

2021/05/16 09:41 編集

> 両者を区別するstaticやインスタンスみたいな故障はないのでしょうか。 いかにクラス内部での操作とは言え、インスタンスメソッド、staticメソッドで充分それらを表せられるので、あえてそれを更に区別する呼称は無いはずです。例えばHogeクラス内部の実装であれば (1) インスタンスメソッドMethod1() this.Method1(); Method1(); (2) staticメソッドMethod2() Hoge.Method2(); Method2(); とのコードで呼び出せます。this.やクラス名.が無いコードでの呼び出しはそのメソッドの定義からコード全体の文脈で判断できますので、あえて特別な呼称の必然性は無いです。 [※一部誤字修正済み]
zenobread

2021/05/16 09:44

理解いたしました。ご説明ありがとうございます。
guest

回答3

0

staticメソッドはインスタンスの有無に関わらず存在します。
また、staticメソッドは、どのインスンタンスにアクセスしていいかを知らないので、引数等でインスタンスを受け取らない限りはインスタンスメソッドにはアクセス出来ません。

例えば、

C#

1 class Test 2 { 3 private int _Value; 4 5 public void Increment() 6 { 7 _Value++; 8 } 9 10 // これは無理 11 //public static void StaticIncrement() 12 //{ 13 // Increment(); 14 //} 15 16 // これはOK 17 public static void StaticIncrement(Test test) 18 { 19 test.Increment(); 20 } 21 }

こんな感じで、自身の値に1加算するIncrementというメソッドがあったとします。
Testクラスのインスタンスはtest1, test2のように複数存在出来ますが、staticメソッド側はIncrementを呼ぼうにも、どのtestに対してのIncrementを呼べばいいか判りません。

投稿2021/05/16 09:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

zenobread

2021/05/16 09:31

コード付きでご回答いただきありがとうございます。 ご回答から考えて、Testというクラスを定義した段階では_ValueやIncrement()は実体がなく、StaticIncrement()はクラス定義した段階で実体がある、ということでしょうか
退会済みユーザー

退会済みユーザー

2021/05/16 09:40

そうです
zenobread

2021/05/16 09:51

承知いたしました。ありがとうございます。 質問事項についてほぼ理解致しましたが、ほかの方のご回答について連絡を差し上げておりますので、ベストアンサーについて今しばらくお待ちください
guest

0

ベストアンサー

staticな関数や変数をインスタンス化するわけではないからstaticメソッド内で何を参照しようが問題ないのでは

通常のインスタンスメソッドやプロパティはインスタンスと結びついたものである以上、特定のインスタンスに対してしか呼べません。

staticメソッドはインスタンスと結びつかない環境ですので、インスタンスメソッドを呼ぶには別途でインスタンスを用意する必要があります。

投稿2021/05/16 08:51

maisumakun

総合スコア146018

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

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

maisumakun

2021/05/16 08:51

> staticメソッド内で何を参照しようが問題ないのでは 「インスタンスを指定して」そこに対して参照を行うことは何も問題ありません。
maisumakun

2021/05/16 08:54

通常のメソッド内では呼ばれたインスタンスを指すthisが存在して、プロパティやメソッドへのアクセスも「thisへの」アクセスとして解釈されます。 staticメソッドはインスタンスと結びつかない以上、thisは存在しません。
zenobread

2021/05/16 09:14

maisumakun様 ご回答ありがとうございます。 ご回答していただいた通り、インスタンスメソッドとプロパティはインスタンスと結びついたものである、ということについて理解致しました。ありがとうございます。 説明が難しいのですが、y_waiwai様のご回答と合わせて 「インスタンスプロパティはインスタンスごとに生成され(このインスタンスが実体?)、インスタンスが生成されないとプロパティとメソッドも生成されない。そのためインスタンスが生成されているかstaticメソッド側から確認できないからインスタンスメソッドやプロパティも参照できない」 ということでよろしいでしょうか。
maisumakun

2021/05/16 10:22

「インスタンスが生成されているかstaticメソッド側から確認できないから」ではなく、「どのインスタンスにアクセスすればいいかわからないから」です。
zenobread

2021/05/16 11:29

そもそも確認云々が問題ではなく、アクセス先が分からないからですね。ありがとうございます。
guest

0

それらは、インスタンスから参照するものです。
インスタンスが存在しないのでエラーになりますね

投稿2021/05/16 08:40

y_waiwai

総合スコア88042

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

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

zenobread

2021/05/16 08:46

y_waiwai様 ご回答ありがとうございます。 大変申し訳ございません。理解不足なのですが、「インスタンスが存在しないのでエラー」とはどういう状態でしょうか
y_waiwai

2021/05/16 08:58

インスタンスから参照するものなので、まずはインスタンスを作って参照しましょう。 それをしてないからエラーとなります
zenobread

2021/05/16 09:16

理解不足で申し訳ないのですが、 「インスタンスプロパティはインスタンスごとに生成され(このインスタンスが実体?)、インスタンスが生成されないとプロパティとメソッドも生成されない。そのためインスタンスが生成されているかstaticメソッド側から確認できないからインスタンスメソッドやプロパティも参照できない」 他の方からのご回答も参照してこのように考えたのですが、この考えでよろしいでしょうか
y_waiwai

2021/05/16 09:22

public static void AD()//NG??? { A a=new A(); a.BA(); } #コレが実行できるかどうかはしらんけど
zenobread

2021/05/16 09:35

>#コレが実行できるかどうかはしらんけど 失礼します。こちらの言葉の意味としては記述されたメソッドについて、「通常は実行できるが、何かが原因で実行されないタイミングがある」ということでしょうか。
y_waiwai

2021/05/16 09:37

まずはやってみれば。
zenobread

2021/05/16 09:50

はい、実行してみて問題ありませんでした。 「~この考えでよろしいでしょうか」ということに対し、正誤の返答ではなくコードと上記補足分があったため、当方は「その考えがあっているか間違っているか、というのは状況によって異なるため正誤ではなくコードにてご返信された」と考えております。 そのうえで「実行できるかどうかわからない」と補足されておられるので、「どういった状況で実行が不可能になる場合があるのか」ご教授お願いします。
y_waiwai

2021/05/16 10:12

なぜこれでエラーが出ないのか、なぜあなたのコードでエラーが出るのか、を理解しましょう。 たんに、 実行できるようなコードかどうかまでは見ていない、というだけです。 実行したらエラーが出るかどうか、はあなたがチェックしましょう。
zenobread

2021/05/16 11:29

はい、わかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問