C#_get_set存取器



在C#中 對於存取private 變數有特殊語法存在~~

在上篇文章中我們學到了如果想要防止外面的人
對我們的class做些 不正當操作

【Solution】:先把這個變數用private藏在class中

在提供一些  public method 當作中間人(與外部溝通的橋樑)
讓大家進行操作與檢視

這是上次的寫法

Class部分



主程式部分


現在要和大家分享另一個寫法


寫法一般是


存取修飾子  變數型別  變數名稱
{
        get{   return ..... ;}
        set{
                  if(....)
                     .......;
                  else
                      ...... ;
             }
}

以下面來說
就是更改User  的  Class 建立一個叫做

HP的屬性

在細微一點的解釋就是指

User這個類別  使用了 hp 這項 private 欄位(成員變數) 建立出了 HP屬性

這種特別的寫法就稱為 Accessors(存取器)
擁有   get  以及  set 兩塊程式Block的存取器



get :  主要負責取得 欄位的值---->return一個值
           ==>在讀取HP時自動呼叫
set : 指定欄位值,透過if條件來判斷值的範圍搭配指派運算將欄位指定成value的值
           ==>在存入數值時自動呼叫


在此呼叫了 user.HP

C# 會自動 呼叫 HP 中的 get 程式碼
(在讀取大HP時自動呼叫 get區塊 回傳 小 hp的值)



.........  // 宣告變數(通常是 public)
{
    get { .... } // 希望變數讀取時執行的程式碼
    set { .... } // 希望數值存入時執行的程式碼
}




Class程式碼


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace class_exercise
{
    class User
    {
        //public string userName;
        private string userName; // 改成private不讓他人改
        private string passWord;//不讓人修改它

        private int hp; // 生命值
        public User(string userName, string passWord)
        {
            this.userName = userName;
            this.passWord = passWord;

            this.hp = 20;
        }

        public int HP
        {
            get
            {
                return hp;
            }

            set
            {
                if (value < 0)  //  value 是在存入數值的時候準備存入的數值會自動產生出來的供其存取
                    hp = 0;
                else
                    hp = value;
            }
        }

        public void hurt(int decreaseHP)
        {
            if (hp >= decreaseHP)
                hp -= decreaseHP;
            else
                hp = 0;
        }
        public int getHP()
        {
            return hp;
        }


       

            

        public bool comparePassword(string targetPassword)
        {
            if (this.passWord == targetPassword)
                return true;
            else
                return false;
        }

        //可能會有人忘記密碼或是輸入錯誤!!!
        private void reset()
        {
            passWord = "";
        }
        //搜尋結果
        //「可遠觀而不可褻玩焉
        public string getUserName()
        {
            return userName;
        }

    }
}



主程式碼

測試一. 用存取器get秀值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace class_exercise
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User("kuanyu","1234");
            //user.hurt(10);
            //user.hurt(10);

            //Console.WriteLine(user.getHP());
            Console.WriteLine(user.HP);
            Console.ReadKey();
        }
    }
}


測試二. 用存取器set存數值進去供public int HP屬性去做判斷

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace class_exercise
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User("kuanyu","1234");
            //1.藉由存取器get 秀值
            Console.WriteLine(user.HP);
            //2.藉由set存數值進去
            user.HP = 60;
            Console.WriteLine(user.HP);
            user.HP = -1;
            Console.WriteLine(user.HP);


            Console.ReadKey();
        }
    }
}





今天若想要看 HP的數值就會呼叫   get  後面的程式碼

如果是想存數值進去就呼叫     set 後方程式碼


==========================================================

假設今天我在   使用者  或是  玩家  這個  類別

要設計存   它有幾個  不同種類的 硬幣

1塊錢  、 5塊錢 、  10塊錢

要個別存有多少個的話



在 物件剛開始的時候  分別指定  1塊錢  5塊錢  10塊錢分別各有1枚硬幣

count1  : 計算有幾個1塊錢
count5  : 計算有幾個5塊錢
count10  : 計算有幾個10塊錢

這時你會發現  User類別  當中 有  層級資訊

此時若我想得知玩家總共的錢有多少

最直觀的作法就是

把  count1   *  1   、  count5 * 5 、 count10 * 10 通通加總起來

即可

我們可以再寫一個  public method 來做
【寫法1. public method】






又或者用  get   及  set  存取器來做
【寫法2.用  get   及  set  存取器來做】




get  、 set 存取器 好處是
可以把一些計算 ,用變數的方式去作呈現




主程式碼


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace class_exercise
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User("kuanyu","1234");

            //Console.WriteLine( user.Money );
            Console.WriteLine( user.total());

            Console.ReadKey();
        }
    }
}


Class程式碼


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace class_exercise
{
    class User
    {
        //public string userName;
        private string userName; // 改成private不讓他人改
        private string passWord;//不讓人修改它
        private int hp; // 生命值

        private int count1, count5, count10;
        
        public User(string userName, string passWord)
        {
            this.userName = userName;
            this.passWord = passWord;

            this.hp = 20;
            this.count1 = 1;
            this.count5 = 1;
            this.count10 = 1;
        }
        public int total()
        {
            return ( count1 + count5 * 5 + count10 * 10 );
        }

        public int Money
        {
            get { return count1 + count5 * 5 + count10 * 10; }
        }



        public int HP
        {
            get
            {
                return hp;
            }

            set
            {
                if (value < 0)
                    hp = 0;
                else
                    hp = value;
            }
        }

        public void hurt(int decreaseHP)
        {
            if (hp >= decreaseHP)
                hp -= decreaseHP;
            else
                hp = 0;
        }
        public int getHP()
        {
            return hp;
        }


       

            

        public bool comparePassword(string targetPassword)
        {
            if (this.passWord == targetPassword)
                return true;
            else
                return false;
        }

        //可能會有人忘記密碼或是輸入錯誤!!!
        private void reset()
        {
            passWord = "";
        }
        //搜尋結果
        //「可遠觀而不可褻玩焉
        public string getUserName()
        {
            return userName;
        }

    }
}



最後統整

【1.】只使用 get 而去除 set 的話,該變數將會變為唯讀

我們也可以把 set 拿掉  只留下 get

就變成  可遠觀而不可褻玩焉 的 唯讀 變數

【2.】使用 Get及Set 存取器時,不一定要有對應的
private 變數















留言

這個網誌中的熱門文章

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header

經得起原始碼資安弱點掃描的程式設計習慣培養(三)_7.Cross Site Scripting(XSS)_Stored XSS_Reflected XSS All Clients

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題