MADOCHAN BLOG

強いプログラマーを目指す30代のブログ



C#で外部から変数を操作できるプロパティ(get, set)機能について詳しく解説

外部から変数の値の取得や設定をするときに使う、C#の機能であるプロパティの使い方を知っていますか?
プロパティの意味は知っていても、具体的な使い方を知らない人もいるのではないでしょうか。

また、プロパティを用いて外部から値の取得や設定をする理由について、疑問に思ったことはありませんか?
「よくわからないけどプロパティを使ったほうが良いらしいから使っておこう…」と疑問をそのままにして使っている人もいるかもしれませんね。

そこで今回は、プロパティの具体的な使い方、プロパティが必要な理由、簡単に使いこなすためのテクニックなどについて解説します!

「プロパティの使い方を詳しく理解したい」「プロパティが必要な理由を知りたい」という人におすすめです!

get, setで変数の値にプロパティを設定する方法

まず、get, setを用いるプロパティの基本的な書き方を解説します。

private 変数名;

アクセス修飾子 データ型 プロパティ名
{
    get
    {
            // 値を取得する際に行いたい処理
        return 変数名;
    }
    set
    {
            // 値を設定する際に行いたい処理
        変数名 = value;
    }
}

アクセス修飾子とは、publicやprotectedなどの外部からのアクセスの許容範囲を設定するものです。

getでは値の取得を行うため、取得させる値をreturnしています。
setは設定する値をvalueで受け取ってくれるため、変数 = valueと変数にvalueを代入しています。

上記のように記述することで、privateで宣言された変数に対して、プロパティの設定が可能です。

プロパティで値を取得・設定する方法

次に、プロパティで値を取得・設定をする方法について解説します。

プロパティを設定した変数の値に対して値の取得・設定をするためには、プロパティ名を用います。

using System;

namespace Test
{
    class Product
    {
        private string productName = "パンダのぬいぐるみ";

        // プロパティ
        public string ProductName
        {
            get
            {
                return this.productName;
            }
            set
            {
                this.productName = value;
            }
        }
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();
            Console.WriteLine("製品の名前は" + product.ProductName + "です。"); 
        }
    }
}
製品の名前はパンダのぬいぐるみです。

private宣言された変数productNameの値に対して、設定したProductNameというプロパティ名を用いることで、外部クラスで値が取得することができました。

このように、プロパティ名を用いて値の取得・設定をします。

C#のget,setが必要な理由とは?

ただ、プロパティを設定するとコードは長くなってしまいます。

そのため、「プロパティを設定する必要はあるのか」「プロパティを使わずに外部クラスからの値の取得・設定はできないのか」と疑問を持つ人もいるかもしれませんね。

そんな人向けに、プロパティが必要な理由について解説します。

private宣言された変数は、外部クラスから値を取得も設定もできません。

using System;

namespace Test
{
    class Product
    {
        private string productName = "パンダのぬいぐるみ";
        private int price = 3000;
        private string category = "ぬいぐるみ";        
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();
            Console.WriteLine("製品の名前は" + product.productName + "です。"); // エラーとなる
        }
    }
}

上記の例では、Productクラスでprivate宣言された変数productNameの値を、Introductionクラスで取得して表示しようとしています。しかし、実行をすると『productNameの変数にアクセスできません』というエラーになってしまいます。

このとき、private宣言された変数をエラーにせず、外部クラスから変数を操作する方法がプロパティです。

using System;

namespace Test
{
    class Product
    {
        private string productName = "パンダのぬいぐるみ";

        // プロパティ
        public string ProductName
        {
            get
            {
                return this.productName;
            }
            set
            {
                this.productName = value;
            }
        }
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();
            Console.WriteLine("製品の名前は" + product.ProductName + "です。"); 
        }
    }
}
製品の名前はパンダのぬいぐるみです。

getとsetを使って、変数productNameのプロパティを設定しています。

productNameはprivate宣言されていますが、プロパティを用いたことで、外部クラスであるIntroductionクラスから値を取得することができました。

変数の宣言にpublicを用いれば、外部クラスから値の取得・設定ができるようになります。しかし外部から変数の値を操作するときは、変数のpublic宣言をするのではなく、プロパティを用いたほうが良いです。

プロパティを使って外部からの取得、設定をした方が良い理由については、次で解説しますね。

C#でプロパティを使うメリット

外部からの変数の読み書きを制御できる

以下のように、public宣言された変数でも外部クラスからの変数の読み書きは可能です。

using System;

namespace Test
{
    class Product
    {
        public string productName = "パンダのぬいぐるみ";
        public int productPrice = 3000;
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();

            // productNameを取得
            Console.WriteLine("製品の名前は" + product.productName + "です。");

            // productPriceの値設定
            product.productPrice = 500;
            Console.WriteLine("製品の価格は" + product.productPrice + "円です。");
        }
    }
}
製品の名前はパンダのぬいぐるみです。
製品の価格は500円です。

上記の場合、値の取得も設定も可能なので、価格を勝手に書き換えられています。このようにpublic宣言の変数の場合、制限なく外部クラスで値の取得や設定ができてしまうのです。

ちょっとした数字であれば問題ないかもしれませんが、アプリの設定のように核となるデータを誰でも変更できるようになってしまうと、アプリが使えなくなる事故につながってしまいます。このようなリスクを回避するために、外部からの取得や設定には制限が必要なのです。

プロパティを用いれば、制限することができます。

次のように書くことで、値の取得だけをするように制御することができます。

using System;

namespace Test
{
    class Product
    {
        private string productName = "パンダのぬいぐるみ";
        private int productPrice = 3000;

       // productNameのプロパティ
        public string ProductName
        {
            get
            {
                return this.productName;
            }
            set
            {
                this.productName = value;
            }
        }

        // productPriceのプロパティ
        public int ProductPrice
        {
            // productPriceの取得
            get
            {
                return this.productPrice;
            }
          
            private set 
            {
                this.productPrice = value;
            }
        }
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();

            Console.WriteLine("製品の名前は" + product.ProductName + "です。");
            // 製品の名前はパンダのぬいぐるみです。
            Console.WriteLine("製品の価格は" + product.ProductPrice + "円です。");
            // 製品の価格は3000円です。
            product.ProductPrice = 500;
            // エラーになる
        }
    }
}

このサンプルでは、外部クラスからproductPriceの値は取得できます。
ただ、setはprivateとして制限をかけているため、外部クラスでproductPriceの値を設定しようとするとエラーになります。

このように、プロパティを用いることで、外部クラスから変数の読み書きの制御ができるのです。

変数を操作するときの処理を追加することができる

プロパティを用いることで、以下のように変数を操作するときの処理を追加することができます。

using System;

namespace Test
{
    class Product
    {
        private string productName = "パンダのぬいぐるみ";
        private int productPrice = 3000;

        public string ProductName
        {
            get
            {
                return this.productName;
            }
            set
            {
                this.productName = value;
            }
        }

        public int ProductPrice
        {
            get
            {
                return this.productPrice;
            }

            set
            {
                // 価格を正数のみ指定可能とする
                if (0 <= value)
                {
                    this.productPrice = value;
                } else {
                        throw new ArgumentException("価格は正数で設定してください");
                }
            }
        }
    }

    class Introduction
    {
        static void Main()
        {
            var product = new Product();

            Console.WriteLine("製品の名前は" + product.ProductName + "です。");

            product.ProductPrice = -500; // 負数なのでエラー表示
            Console.WriteLine("製品の価格は" + product.ProductPrice + "円です。");
            product.ProductPrice = 5000; // 正数なのでproductPriceの値が設定される
            Console.WriteLine("製品の価格は" + product.ProductPrice + "円です。");
        }
    }
}

プロパティの中で処理を記述したことで、『設定できる値を正数のみに限定し、負数であればエラーを表示する』という処理を追加することができました。

プロパティを簡単に記述する自動プロパティとは?

これまでの例ではプロパティの数は1個や2個でしたが、ここでは5個に増やしてみます。

class Product
    {
        private string productName = "パンダのぬいぐるみ";
        private int productPrice = 3000;
        private string category = "ぬいぐるみ";
        private int width = 500;
        private int height = 500;

        public string ProductName
        {
            get
            {
                return this.productName;
            }
            set
            {
                this.productName = value;
            }
        }

        public int ProductPrice
        {
            get
            {
                return this.productPrice;
            }

            set
            {
                if (0 <= value && value <= 5000)
                {
                    this.productPrice = value;
                }
            }
        }

        public string Category
        {
            get
            {
                return this.category;
            }

            set
            {
                this.category = value;
            }
        }

        public int Width
        {
            get
            {
                return this.width;
            }

            set
            {
                this.width = value;
            }
        }

        public int Height
        {
            get
            {
                return this.height;
            }

            set
            {
                this.height = value;
            }
        }
    }

変数の数を増やせば、プロパティの数は増えます。1個や2個であれば気になりませんが、5個だと少し冗長ですよね。

冗長な記述をシンプルにする方法として、自動プロパティがあります。
自動プロパティを用いることで、以下のように簡潔に書き換えることができるのです。

class Product
{
  string ProductName { get; set; } = "パンダのぬいぐるみ";
  int ProductPrice { get; set; } = 3000;
  string ProductCategory { get; set; } = "ぬいぐるみ";
  int Width { get; set; } = 500;
  int Height { get; set; } = 500;
}

何十行もあったコードがとてもすっきりとしました。このように、自動プロパティは記述をシンプルにしてくれます。

自動プロパティの書き方は、次のとおりです。

データ型 プロパティ名 { get; set; } = 初期値;

ただ、変数を操作するときの処理を追加する場合は自動プロパティが使えません。単純に変数の値の読み書きを設定するときに、使うことができます。

まとめ

外部クラスから、値の操作を可能にするプロパティについて解説しました。

同じ外部クラスからの操作を可能にするpublic宣言よりも、読み書きの制限や操作時に処理を追加できるプロパティは、とても便利です。

ぜひ、使ってみてくださいね!