首頁  >  文章  >  後端開發  >  C#基礎知識整理:基礎知識(10) 靜態

C#基礎知識整理:基礎知識(10) 靜態

黄舟
黄舟原創
2017-02-11 13:23:001245瀏覽

    如果想存取某個類別的方法或屬性,請務必先實例化該類,然後用該類別的物件加.號存取。例如:
有一個使用者類別和一個處理密碼(加密和解密)的類別。沒產生一個使用者實例後,處理密碼類別要對密碼進行加密和解密。

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace YYS.CSharpStudy.MainConsole.Static
{
    /// <summary>
    /// 用户类
    /// </summary>
    public class User
    {
        //加密解密用到的Key
        private string key = "20120719";
        //加密解密用到的向量
        private string ivalue = "12345678";

        private string userName;

        private string userEncryptPassword;

        private string userDecryptPassword;

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get
            {
                return userName;
            }
        }
        /// <summary>
        /// 用户密码,加密后的密码
        /// </summary>
        public string UserEncryptPassword
        {
            get
            {
                return userEncryptPassword;
            }
        }
        /// <summary>
        /// 用户密码,解密后的密码
        /// </summary>
        public string UserDecryptPassword
        {
            get
            {
                DES des = new DES();

                this.userDecryptPassword = des.Decrypt(userEncryptPassword, key, ivalue);

                return userDecryptPassword;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPassword"></param>
        public User(string userName, string userPassword)
        {
            this.userName = userName;

            DES des = new DES();

            this.userEncryptPassword = des.Encrypt(userPassword, key, ivalue);
        }
    }

    /// <summary>
    /// 处理密码的类
    /// </summary>
    public class DES
    {
        /// <summary>
        /// 加密字符串
        /// </summary>
        public string Encrypt(string sourceString, string key, string iv)
        {
            try
            {
                byte[] btKey = Encoding.UTF8.GetBytes(key);

                byte[] btIV = Encoding.UTF8.GetBytes(iv);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = Encoding.UTF8.GetBytes(sourceString);
                    try
                    {
                        using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                        {
                            cs.Write(inData, 0, inData.Length);

                            cs.FlushFinalBlock();
                        }

                        return Convert.ToBase64String(ms.ToArray());
                    }
                    catch
                    {
                        return sourceString;
                    }
                }
            }
            catch { }

            return sourceString;
        }

        /// <summary>
        /// 解密字符串
        /// </summary>
        public string Decrypt(string encryptedString, string key, string iv)
        {
            byte[] btKey = Encoding.UTF8.GetBytes(key);

            byte[] btIV = Encoding.UTF8.GetBytes(iv);

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Convert.FromBase64String(encryptedString);
                try
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);

                        cs.FlushFinalBlock();
                    }

                    return Encoding.UTF8.GetString(ms.ToArray());
                }
                catch
                {
                    return encryptedString;
                }
            }
        }
    }
}

呼叫:

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User("yangyoushan", "000000");

            Console.WriteLine(string.Format("用户名:{0}", user.UserName));

            Console.WriteLine(string.Format("加密后的密码:{0}", user.UserEncryptPassword));

            Console.WriteLine(string.Format("明文的密码:{0}", user.UserDecryptPassword));

            Console.ReadKey();
        }
    }

結果:

 

這兩個類別實現的程式碼裡面,有兩個問題。
1、每實例化一個user,都要運作

            DES des = new DES();

            this.userEncryptPassword = des.Encrypt(userPassword, key, ivalue);

    也就是每次都要實例化一個DES實例。這樣是不好的,實例化DES只是為了呼叫它的方法而已,但是每次呼叫方法都有要實例化卻是不太方便,而且也增加了記憶體的消耗。
2、對於

        //加密解密用到的Key
        private string key = "20120719";
        //加密解密用到的向量
        private string ivalue = "12345678";

    這兩個變數是每個user實例都要用到的,而且不會改變。但是每實例化一個user都要分配空間,同樣也是對記憶體有消耗的,而且就面向對象思想來說,也不大合理。

既然這樣,那麼最好是將DES的兩個方法公用出來,而且不用透過實例化就能直接呼叫就好。例如Math的所有方法(Math.Abs​​(1);)。再一個就是將User裡的key和ivalue變數也設定為公用,而且也可以直接訪問,並且只分配一次記憶體空間,而實例化user時不用再另外分配了。
    這就要用到靜態,也就是static關鍵字。所謂靜態就是,成員被一個類別所共享。也就是說被宣告為靜態的成員不屬於一個特定的類別的對象,屬於這個類別所有對象。所有類別的成員都可以宣告為靜態,可以宣告靜態欄位、靜態屬性或靜態方法。不過這裡要區別一下const和static,const是指常數在程式運行中是不能改變值的,static則可以在運行中改變值,而且一個地方改變,其它地方訪問到的都是改變後的值。
這樣可以利用靜態,來最佳化上述的程式碼,如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace YYS.CSharpStudy.MainConsole.Static
{
    /// <summary>
    /// 用户类
    /// </summary>
    public class User
    {
        //加密解密用到的Key
        private static string key = "20120719";
        //加密解密用到的向量
        private static string ivalue = "12345678";

        private string userName;

        private string userEncryptPassword;

        private string userDecryptPassword;

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get
            {
                return userName;
            }
        }
        /// <summary>
        /// 用户密码,加密后的密码
        /// </summary>
        public string UserEncryptPassword
        {
            get
            {
                return userEncryptPassword;
            }
        }
        /// <summary>
        /// 用户密码,解密后的密码
        /// </summary>
        public string UserDecryptPassword
        {
            get
            {
                //使用静态方法和静态字段
                this.userDecryptPassword = DES.Decrypt(userEncryptPassword, key, ivalue);

                return userDecryptPassword;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPassword"></param>
        public User(string userName, string userPassword)
        {
            this.userName = userName;

            this.userEncryptPassword = DES.Encrypt(userPassword, key, ivalue);
        }
    }

    /// <summary>
    /// 处理密码的类
    /// </summary>
    public class DES
    {
        /// <summary>
        /// 加密字符串
        /// </summary>
        public static string Encrypt(string sourceString, string key, string iv)
        {
            try
            {
                byte[] btKey = Encoding.UTF8.GetBytes(key);

                byte[] btIV = Encoding.UTF8.GetBytes(iv);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = Encoding.UTF8.GetBytes(sourceString);
                    try
                    {
                        using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                        {
                            cs.Write(inData, 0, inData.Length);

                            cs.FlushFinalBlock();
                        }

                        return Convert.ToBase64String(ms.ToArray());
                    }
                    catch
                    {
                        return sourceString;
                    }
                }
            }
            catch { }

            return sourceString;
        }

        /// <summary>
        /// 解密字符串
        /// </summary>
        public static string Decrypt(string encryptedString, string key, string iv)
        {
            byte[] btKey = Encoding.UTF8.GetBytes(key);

            byte[] btIV = Encoding.UTF8.GetBytes(iv);

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Convert.FromBase64String(encryptedString);
                try
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);

                        cs.FlushFinalBlock();
                    }

                    return Encoding.UTF8.GetString(ms.ToArray());
                }
                catch
                {
                    return encryptedString;
                }
            }
        }
    }
}

運作結果:

    不過要注意一個問題,一般方法可以存取方法外的靜態屬性或靜態方法。但是如果是靜態方法中要存取方法外的屬性或方法,那麼被存取的屬性和方法也必須是靜態的。因為一般的屬性或方法只有在實例化後才分配空間,才可以使用,而靜態中則是直接在編譯的時候就分配好了記憶體空間,因此靜態方法中呼叫其它的屬性或方法是不可以的,只能呼叫同時靜態的才可以。

以上就是C#基礎知識整理:基礎知識(10) 靜態的內容,更多相關內容請關注PHP中文網(www.php.cn)!

 

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn