日期: 2008-6-10
学习内容:析构,方法,属性
遗留问题:
学习总结:
1.       析构
知识一:垃圾回收机制,CLR规定第0代的存储空间一般为256k,第一代的存储空间为 2M ,第三代的存储空间为 10M
知识点二:一个类只能有一个析构器;析构器不能被继承和重载;析构器不能被调用,它们被自动调用;析构器不能代修饰
知识点三:C#中的Finalizer(终结器)和C++中的Destructor(析构器)的工作原理是不相同的,建议不要在类中定义析构器,因为他会延长对象的声明周期,系统的效率会下降
知识点四:显示的告诉CLR进行垃圾回收的方法:GC.Collect();微软强烈建议不要这么做
知识点五:CLR只能自动释放托管堆中的资源,对于一些非托管堆中的资源(文件,网络,SSL等)需要对他手动进行释放,对象名.Close()或对象名.Dispose()。进行手动释放后,系统不在执行终结器中的Finalize()方法
知识点六:那些情况下会导致Finalize()方法被调用,第0代对象充满,代码显示的调用System.CGCollect()方法,Windows报告内存不足,CLR卸载引用程序域,CLR被关闭
2.       方法
知识点一:方法的参数传递机制,值参数传递,引用参数传递,输出参数传递
代码实例:
using System;
namespace ConsoleApplication2
{
    class Program
    {
        public static void ValueMethod(int i)// 值参数传递方法
        {
            i++;
        }
        public static void RefMethod(ref int i)// 引用参数传递方法
        {
            i++;
        }
        public static void OutMethod(out int i)// 输出参数传递方法
        {
            i = 0;
            i++;
        }
        static void Main (string[] args)
        {
            int i = 0;
            ValueMethod(i);
            Console.WriteLine("i="+i);
            int j = 0;
            RefMethod(ref j);
            Console.WriteLine("j=" + j);
            int k;
            OutMethod(out k);
            Console.WriteLine("k=" + k);
        }
    }
}
知识点二:向方法传递可变参数的方法是使用params关键字
代码实例:
using System;
namespace ConsoleApplication2
{
    class Program
    {
        static int addi(params int[] values)// 定义向方法传递可变参数的方法
        {
            int sum = 0;
            foreach (int i in values)
            {
                sum += i;
            }
            return sum;
        }
        static void Main (string[] args)
        {
            Console.WriteLine(addi(1,2,3,4,5,6));
        }
    }
}
知识点三:使用数组作为参数传递他的值会发生改变,因为他是引用类型。字符串也是引用类型但是它的值不会发生改变,这是由字符串的特性决定的,字符串在声明之后是不可变的,他在托管堆中创建一个副本进行操作
知识点四:共享变量。如果两个以上的方法要共享一个变量则要将此变量声明在类阶层。和局部变量不同的地方在于,类级别变量的生命周期是在此类加载到内存时就自动的分配内存空间,要等到此对象被CLR的垃圾回收器回收时,才会释放掉所占用的内存空间。使用共享变量的方法是在成员变量的名称前面加上static关键字
 
输出参数和引用参数的区别:
       CLR的角度看,关键字out和关键字ref是等效的,这就是说,无论使用哪个关键字,都会生成相同的元数据和IL代码。但是,c#编译器将两个关键字区别对待,在c#中,这两个关键字的区别在于哪个方法负责初始化引用对象。如果方法的参数标记为out,那么调用者不希望在调用方法前初始化对象,被调用的方法不能读取对象的值,而且被调用的方法必须在返回之前为对象赋值。如果方法的参数标记为ref,那么调用者必须在调用方法之前首先初始化参数的值,被调用的方法可以读取参数或为参数赋值
 
值类型和引用类型:
 
类型区分为两大类的主要原因是在于执行性能与内存资源管理的不同。由于值类型变量直接在堆栈(stack)中存储该类型的值,此类类型在内存的使用上以及访问的效能上比引用类型更好。因为引用类型变量存放的是指向实际对象的指针,因此访问对象时必须多进行一次内存引用的操作方可获取数据。且引用类型的对象必须分配多余的内存来存放虚函数指针及线程同步块,对于内存的需求较大。而引用类型的优点是回收站会自动替您管理分配在托管堆(Managed Heap)当中的内存。
 
 
值类型变量和引用类型变量
 
值类型
引用类型
变量中存放
真正的数据
指向数据的引用指针
内存空间分配
堆栈 (stack)
托管堆 (Managed Heap)
内存需求
一般来说较少
较大
执行效能
较快
较慢
内存释放时间点
执行超过定义变量的作用域
由回收站负责回收
可以为 null
不可
可以
 
3.       属性
 
属性是类,结构和接口的命名成员。它们提供了通过访问器(accessor)读或写或计算私有字段的灵活机制。属性是这样的成员:它们提供灵活的机制来读取,编写或计算私有字段的值。可以像使用公共数据成员一样使用属性,但实际三它们是称为“访问器”的特殊方法。这使得数据在可被轻松访问的同时,仍能提供方法的安全性和灵活性。
属性使用实例:
using System;
namespace ConsoleApplication2
{
    class Property
    {
        private string m_Name;
        private string m_Sex;
        public string Name
        {
            set
            {
                m_Name = value;
            }
            get
            {
                return m_Name;
            }
        }
        public string Sex
        {
            set
            {
                if (value==" " ||value==" " )
                    m_Sex = value;
                else
                    Console.WriteLine(" 性别只能为男或女" );
            }
            get
            {
                return m_Sex;
            }
        }
    }
    class Program
    {
      
        static void Main (string[] args)
        {
            Property user = new Property();
            user.Name = " 张三" ;
            user.Sex = " " ;
            Console.WriteLine(" 姓名:{0}" +" "+" 性别:{1}" ,user.Name,user.Sex);
 
        }
    }
}
静态属性的例子:
using System;
class User
{
    private static int logincount;// 定义静态成员变量,用以存储登陆网站的人数
    public User()//User 类的构造方法
    {
        logincount++;
    }
    public static int Log// 定义静态的属性Log
    {
        get
        {
            return logincount;
        }
    }
}
class Program
{
    static void Main (string[] args)
    {
        User a = new User();
        User b = new User();
        User c = new User();
        Console.WriteLine(User.Log);
    }
}