0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C#で static メソッドからインスタンスフィールドにアクセスできない理由

Last updated at Posted at 2025-05-28

導入

Unityでゲームを作っている時、シングルトンパターンを使用したことはありますか?
このパターンを使うにあたって、Staticという修飾子を使用した変数を使用したのではないでしょうか。

その時に一度は

静的でないフィールド、メソッド、またはプロパティ '○○' で、オブジェクト参照が必要です

というエラーを見た事かもしれません。
これについて解説します。

動作環境

JetBrain Rider 2024.3.3

サンプルコード

このコードにはProgramというクラスがあり、中のHumanクラスとMainメソッドが主要な構成です。

using System;

class Program
{
    public class Human
    {
        public Human(string name) => Name = name;

        public static string FamilyName = "FamilyName";
        public string Name = "Name";

        public override string ToString() => $"{FamilyName} {Name}";
    }

    static void Main(string[] args)
    {
        // 1.二人の人間を生成。名字も設定する。
        Human person1 = new Human("taro");
        Human person2 = new Human("kanta");
        Human.FamilyName = "Tanaka";

        DisplayPeople(person1, person2);

        // 2.人間の苗字を変える。
        Human.FamilyName = "Sato"; // これはStatic変数をStaticメソッド内で変えている。

        DisplayPeople(person1, person2);

        // 3.誰かの名前を変える。(エラーになる)
        //Human.Name = "hanako"; // これはインスタンス変数をStaticメソッド内で変えている。

        DisplayPeople(person1, person2);

        // 4.一人目の人間の名前を変える。
        person1.Name = "ichiro"; // これはインスタンス変数をインスタンスを指定して変えている。

        DisplayPeople(person1, person2);
    }

    static void DisplayPeople(params Human[] persons)
    {
        Console.WriteLine("---- Display People ----");
        foreach (var person in persons)
        {
            Console.WriteLine(person.ToString());
        }
        Console.WriteLine("------------------------\n");
    }
}

Humanはインスタンス化が可能なクラスです。
中にはインスタンス変数として"名前(Name)"とStatic変数として"苗字(FamilyName)"があります。

解説

1.人間の生成

まず事前にタロウとカンタという二人のインスタンスを生成しています。
また苗字をタナカにしています。
この苗字はStaticなので、タナカはタロウとカンタの両方で使用されます。
段落テキスト.png

出力すると以下が出ます。

Tanaka taro
Tanaka kanta

2.人間の苗字を変える。

ここでは苗字をサトウに変更しています。
苗字の変数はStaticなので、タロウやカンタとは別の領域に変数があります。
イメージとしては、Humanというクラスは人々という概念だと考えます。
Humanという概念の中に苗字という変数があり、苗字はタナカという中身が入っているというイメージです。
なので苗字という変数はHuman達の中で一つしかありません。どれだけ人が増えても苗字という変数は一つのままです。
この単一の変数を変更しているので、神様(Staticメソッド)からもどの変数を変更するかは分かります。
段落テキスト (1).png

出力すると以下が出ます。

Sato taro
Sato kanta

3.誰かの名前を変える。(エラーになるパターン)

ここではインスタンス変数である名前を、Static変数のように使用しようとしてエラーが出ています。
これはHumanとだけ指定されても、どのインスタンスの名前なのかが分からないのでエラーになっています。
"誰か"の名前を変えるというのも、プログラム的には候補者リストを作る必要があります。
段落テキスト (3).png

静的でないフィールド、メソッド、またはプロパティ 'Program.Human.Name' で、オブジェクト参照が必要です

4.一人目の人間の名前を変える。

ここでは一人目の人間の名前をイチロウに変更しています。
MainメソッドはStaticで、名前はインスタンス変数なので、エラーが起きそうですが、これは大丈夫です。
なぜならインスタンスを指定しているからです。
"一人目"と指定しているので、エラーにはなりません。
段落テキスト (2).png

おわり

このようにStaticのエラーになる場合は、Staticとインスタンスの関係を考えてみてください!
この原理を掴めばこのエラーの直す方針が分かるようになるでしょう!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?