C#基础知识整理:基础知识(10) 静态
有一个用户类和一个处理密码(加密和解密)的类。没生成一个用户实例后,处理密码类要对密码进行加密和解密。
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)!