특정 클래스의 메서드나 속성에 액세스하려면 먼저 클래스를 인스턴스화한 다음 클래스 개체와 기호를 사용하여 액세스해야 합니다. 예를 들면 다음과 같습니다.
사용자 클래스와 비밀번호(암호화 및 복호화)를 처리하는 클래스가 있습니다. 사용자 인스턴스가 생성되지 않은 후에는 비밀번호 클래스가 비밀번호를 암호화하고 해독해야 합니다.
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. 인스턴스화된 각 사용자에 대해
DES des = new DES(); this.userEncryptPassword = des.Encrypt(userPassword, key, ivalue);
를 실행합니다. 이는 DES 인스턴스가 매번 인스턴스화되어야 함을 의미합니다. 이는 좋지 않습니다. DES는 단지 메소드를 호출하기 위해 인스턴스화하지만, 메소드를 호출할 때마다 인스턴스화하는 것은 불편하고 메모리 소모도 늘어납니다.
2.
//加密解密用到的Key private string key = "20120719"; //加密解密用到的向量 private string ivalue = "12345678";
의 경우 이 두 변수는 모든 사용자 인스턴스에서 사용되며 변경되지 않습니다. 하지만 사용자가 인스턴스화될 때마다 공간을 할당해야 하고, 이 역시 메모리를 소모하며, 객체지향적 사고 측면에서는 그다지 합리적이지 않습니다.
이 경우에는 DES의 두 메소드를 공유하여 인스턴스화하지 않고 직접 호출하는 것이 가장 좋습니다. 예를 들어 Math의 모든 메서드(Math.Abs(1);)입니다. 또 다른 방법은 User에서 key, ivalue 변수를 public으로 설정하는 방법인데, 직접 접근도 가능하고, 메모리 공간은 한 번만 할당되므로 user를 인스턴스화할 때 별도로 할당할 필요가 없습니다.
이를 위해서는 static, 즉 static 키워드를 사용해야 합니다. 소위 정적이란 클래스가 멤버를 공유한다는 것을 의미합니다. 즉, static으로 선언된 멤버는 특정 클래스의 개체에 속하지 않고 해당 클래스의 모든 개체에 속합니다. 클래스의 모든 멤버는 정적으로 선언될 수 있으며 정적 필드, 정적 속성 또는 정적 메서드를 선언할 수 있습니다. 그러나 여기서는 const와 static을 구분해야 합니다. const는 프로그램 실행 중에 상수 값을 변경할 수 없지만 static은 실행 중에 값을 변경할 수 있다는 의미입니다. 다른 곳에서 액세스할 수 있습니다.
이런 방법으로 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 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!