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