最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器。所以正好研究研究。这3个定时器分别是:

//1.实现按用户定义的时间间隔引发事件的计时器。此计时器最宜用于 Windows 窗体应用程序中,并且必须在窗口中使用。
System.Windows.Forms.Timer

// 2.提供以指定的时间间隔执行方法的机制。无法继承此类。
System.Threading.Timer

//3.在应用程序中生成定期事件。
System.Timers.Timer

这三个定时器位于不同的命名空间内,上面大概介绍了3个定时器的用途,其中第一个是只能在Windows窗体中使用的控件。在.NET1.1里面,第3个System.Timers.Timer,也是可以拖拽使用,而.NET2.0开始取消了,只能手动编写代码。而后2个没有限制制。下面通过具体的列子来看3个Timer的使用和区别,网上谈的很多,但基本都没有代码。

System.Windows.Forms.Timer

 

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int num = 0;
        
        private void Form_Timer_Tick(object sender, EventArgs e)
        {
            label1.Text = (++num).ToString();
            Thread.Sleep(3000);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form_Timer.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form_Timer.Stop();
        }
    }

继续阅读

最近在看垃圾回收的IDispose的接口实现,平时经常听到某个类型要执行什么操作需要实现什么接口,某个类型实现了什么接口。但我们用的系统提供的类型都已经实现了这些接口,但到底怎么实现的我们不清楚。所以我们就把这些常用的接口实现在自己的类型中。让他们具有一定功能,也让我认识下这些接口。

下面的例子中一共实现了IComparable,IComparer,IEnumerable,IEnumerator和IDisposable,实现这些接口,我们的类型就可以在List或Array中进行排序,使用foreach进行遍历,手动释放资源或使用using块。在看代码前先说明下,2.0中增加了泛型的支持,所以也有了泛型的接口。我下面说的主要是针对接口,而不管是不是泛型(区别不大),但代码中都是实现的泛型接口。所以看到介绍是非泛型,代码是泛型不要误会,我主要是介绍接口以及实现。

 

 

一 实现IComparable,IComparer接口

 

  • IComparable:定义由值类型或类实现的通用的比较方法,以为排序实例创建类型特定的比较方法。
  • IComparer:定义类型为比较两个对象而实现的方法。

通常我们要在数组或链表中对一个对象进行排序,这就需要对对象进行比较。但因为数组和链表可以存放各种数据,值类型,引用类型,或是我们自建类型,所以它不可能去实现各个类型的比较方法,而需要类型自己实现。所以,.NET中如果一个类型实现了IComparable接口,那么他就可以被排序,因为排序算法知道去调用这个类型的CompareTo方法。但是有时候我们类型有多个字段,需要能选择的进行排序,这个时候就需要在此类型中实现IComparer接口,以便按自己的方式进行排序。如果不实现此接口,系统会自己产生一个默认的实现。但是要注意的是2个接口的实现不是直接在一个类上,而是通过嵌套类。

继续阅读

在前一篇深入了解.NET中继承和多态(上) 中我们已经知道了对象在内存中的布局结构,这一篇我们讲主要研究继承和多态。主要是通过列子来看问题。其中会涉及到使用SOS进行扩展调试和查看IL代码。

 

一 调用方法的IL指令

 

 

我们知道在.NET中一共有三种方法:实例方法,静态方法和虚方法。当程序被编译成IL代码时,我们可以看到有两个调用方法的IL指令,分别是callcallvirt我们首先看下下面的列子:

    class Cpu
    {   
        public Cpu()
        {
            Console.WriteLine("初始化Cpu");
        }
        public void fun()
        {
            Console.WriteLine("Cpu的方法/n");
        }
        public static void fun2(){ }
        
        public virtual void fun3(){ }
        
        public override string ToString()
        {
            return base.ToString();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Cpu c1 = new Cpu();
            c1.fun();           //调用实例方法 
            Cpu.fun2();       //调用静态方法 
            c1.fun3();          //调用虚方法 
            c1.ToString();     //调用重写基类的虚方法 
        }
    }

以下是Main方法的IL代码

继续阅读

注意:在写完文章后很久才发现自己文章中【编译】两个字的让人误解,比如方法槽偏移量是在编译时获得的,其实我想表达的是JIT编译,而不是指IL编译。我大概修改了一些关键地方,但是可能有很多遗漏。大家要自己判断了,哈!

封装、继承、多态是面向对象的最重要的3个特点。但是想真的弄明白他们其中的奥秘还是的费一番功夫。记得在学校学习C++的时候,讲到这个地方,自己早已是一头雾水,当时还在想,弄成private做什么,多麻烦啊。到了多态,继承更是昏死了。今天就来深入了解下其中的奥秘吧。本文主要是从内存结构出发来讲解.NET中的继承和多态,因为内存布局的不同所以和其他语言中的继承多态可能有一定区别。

 

 

一 笔试题目

 

 class Program
    {
        static void Main(string[] args)
        {
            Cpu c1 = new Cpu();
            c1.fun();
            Cpu c2 = new IntelCpu();
            c2.fun();
            Cpu c3 = new CoreCpu();
            c3.fun();
            IntelCpu  c4 = new CoreCpu();
            c4.fun();
        }
    }
    class Cpu
    {   
        public Cpu()
        {
            Console.WriteLine("初始化Cpu");
        }
        public virtual void fun()
        {
            Console.WriteLine("Cpu的方法/n");
        }
    }
    class IntelCpu : Cpu
    {
        public IntelCpu()
        {
            Console.WriteLine("初始化IntelCpu");
        }
        public override void fun()
        {
            Console.WriteLine("IntelCpu的方法/n");
        }
    }
    class CoreCpu : IntelCpu
    {
        public CoreCpu()
        {
            Console.WriteLine("初始化CoreCpu");
        }
        public new void fun()
        {
            Console.WriteLine("CoreCpu的方法/n");
        }
    }

上面是我们常见的关于继承和多态的题目。或许很多人都有一套做这种题目的方法,能够让你准确的得到答案,但是我们了解继承和多态不是为了背公式,不是为了做题目,是未来灵活使用。所以有必要弄清楚她内部到底是怎么实现的。或许平时可能用不上,但是我认为还是会有所帮助的。

继续阅读