如果想访问某个类的方法或属性,一定要先实例化该类,然后用该类的对象加.号访问。比如:
有一个用户类和一个处理密码(加密和解密)的类。没生成一个用户实例后,处理密码类要对密码进行加密和解密。
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) 静态的内容。