>  기사  >  백엔드 개발  >  C# 기본 지식 편집: 기본 지식(10) 정적

C# 기본 지식 편집: 기본 지식(10) 정적

黄舟
黄舟원래의
2017-02-11 13:23:001200검색

특정 클래스의 메서드나 속성에 액세스하려면 먼저 클래스를 인스턴스화한 다음 클래스 개체와 기호를 사용하여 액세스해야 합니다. 예를 들면 다음과 같습니다.
사용자 클래스와 비밀번호(암호화 및 복호화)를 처리하는 클래스가 있습니다. 사용자 인스턴스가 생성되지 않은 후에는 비밀번호 클래스가 비밀번호를 암호화하고 해독해야 합니다.

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 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.