如何学好C# 开篇浅论1-4

时间过得真快,一转眼就是过往云烟啊。回首看一下,C#从最初的1.0 发展到现在的3.0了,历经了数载风雨。这一门新型的语言,在Anders Hejlsberg(前Borland 的首席体系结构设计师)与Scott Wiltamuth等程序开才的带领下发展之快,也是大家有目共睹的。经常可以看到很多人在网上拿java和C#来比较,争个面红耳赤,最终还是没有一个结果。在此我不想再讨论java与C#孰优孰劣.他们各有各的优势,JAVA凭心而论,发展的确比C#要成熟一些,毕竟比C#先出道好些年。其实试想一下即便再强大的语言,如果开发者没有一个好的编程思想,那又怎么样?其总言之,不过是一门语言而已,不过是一个工具而已。
        本来在写这篇文章之前,本来想写一篇更贴近技术的文章,但是经常在网上很多人学习C#很迷茫,不知道自已如何的走下去。“授人以鱼,不如授人以渔”,在此我谈谈我个人的如何学习一些浅薄的见解。
   先简单的介绍一下我自已吧!本人毕业于湖南师大理学院,大学生生活,我想有过大学经历的人都会有所体会,计算机系的大部份的人大学的生活很大一部份是在游戏中度过的,更何况本人在读大学的时候正是游戏的顶峰期。在学校里面学的东西感觉都是应付考试,什么pascal,C,C++,在大学里面都学过,当时也没有仔细出来好好研究一下,纯粹为了考试而考试,真正好好的学习C++是大学的最后的一年,我记得当时的时候我用一年的时间看了<<C++ Primer>>(虽然从字面上看是入门C++书,但个人感觉还是有一定难度的),<<windows 程序设计>>(太经典了,至今还用做参考书),候老师的<<深入浅出MFC>>,总体而言看懂也就60%多吧,毕竟多少还是有点基础的,毕业后到了北京的一家软件公司,工作半年多后,公司新成立一个.NET研发部,并委任本人担任项目经理助理,由于本人一直从事windows做程序,所以也没有反对,于是转向C#,便是一件顺理成章的事情了。说白了,我也就是从C++转型过来的程序员。
        掌握任何一门技术都是一件非常不易的事情,特别是做程序开发。其实在我看来,个人的学习能力是一方面,天才毕竟是少数,熟练使用(特别不喜欢用精通两字,以前记得人民邮电出了一本书<<21天精通C++>>,个人执一直保留意见)一门语言能否成功关键在于毅力和恒心。每个人在学习的过程中,总会觉得自已的水平停止不前了,很难再进步了,也就是常说的超越自已。其实这是通病,我也曾有过。学习C#,个人觉得相对于一门语言来说还是比较容易入门的。主要反映在以下几点:
        1.其语法个人认为非常的优雅,比较接近自然语言(当然在dot net 中的"."号处理的不是很好,命名空间和类的实例成员没有很好的区别开来,用"::"+"."号来区分命名空间和实例成员会更好, 个人看法,有些武断!呵呵).
        2.强大的VS2005。VS2005的IDE(集成开发环境)做得非常优秀,可以用几近完美来形容.用起来非常的顺手。这里提一下一个免费的轻型的开发工具SharpDevelop 1.0,如果用.net framework 2.0现在SharpDevelop 2.0正式版也出来了,这个工具的本身就是用C#开发的。界面类似于vs2003,操做起来也还算方便,适合初学者和电脑配置不是很好的人,不过如果有条件的话,还是直接上vs2005吧,因为SharpDevelop 2.0快捷键没有VS2005的全,相对于VS2005来说使用还是有些不方便,毕竟真的的团队开发,一般还是用VS2005的。当然最好二个都装上更好,最近本人在调试一段程序的时候,居然发现全局的钩子函数在VS2005里面不支持调试。后来切换SharpDevelop 2.0来调试成功.所以最好"一颗红心,两手准备".
        3.详尽中文的本地帮助以及海量的联机帮助系统(即MSDN Library和MSDN,当然不仅仅是C#,还有其它语言,如VC,VB等) 。现在MSDN的中文版不会比英文版迟多久,这样的话,即使英文基础不好的人也可以得到第一手资料,联机的MSDN整个网站有超过1.5TB(1500GB)的软件和文档。相对于其它语言的全英文的帮助系统会会更有利于理解一些。所以新手一定要学会查msdn.一般MSDN Libary会随安装盘一起。
   有了以上的一切,应该更加使我们能够快速掌握这门语言,但为什么我们还会对C#一头雾水?有些C#初学者可能还有别的语言的一些基础,为什么还会出现这样的情况?一个功能或称之为一个模块下来,学了几个月的C#居然不知道从何下手。debug老是通不过,甚至怀疑是C#编译器的bug?于是开始为自已找各种理由,学了两个月还是这样,再换一门语言再试试..............。如果你真的按最后一点去做的话,就完了。可以说如果执有这种思想去学任何一门语言都会矢折的。找出出现错误的原因正是程序最大的乐趣之一,一如即往的坚持下来你会发现你写的代码的错误率会越来越低。当然这可能需要比较长的时间,但请相信我,时间并像你所想像的那样长。你可以通过以下几种方法来提高自已.
        1.多读代码,网上很多好的代码,不要为了实现功能而简单的复制+粘贴,"复制+粘贴"只要会操作电脑的都会,关键学会作者的思想(非常重要啊).
        2.多写代码,然后再不断的改进.
        3.多读好书,不推荐读电子版的书,还是买传统的印刷版好,虽然可能要花一些银子:),但你想像一下,本来写程序就要面对电脑,再每天对
着电脑看书,健康还是非常重要滴!
        4.多多交流.与同行之间的交流也非常的重要,即便可能他不是从事C#开发的.要知道程序设计是相通的。我现在就在把JAVA里面的一些思想
放到C#里面来做。说到这里的同时,欢迎大家跟我一起来交流.以后大家可以称呼我叫小汤,QQ:24046222.
        5.学会休息.遇到实在想不到的问题。可以先放一放,看一下窗外的景色,或者干脆玩一会游戏,呵呵,轻松一下,再回到问题当中去,有时
候你会发现原来不过如此。
        6.及时总结经验.你可以做成书面的,或是电子版的."不积小流无以成汪洋","好记心比不过烂笔头",对以后的查阅是有很大帮助的。
 
       好了,以上都是个人一些愚见,真的很晚了,明天还要上班。下篇我将结合一些代码实例来说明这六点学习方法的重要性.先预祝大家学习愉快!


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tangwei168/archive/2007/01/25/1492942.aspx

上一章提到掌握六点学习C#的学习方法,今天就让我们通过实例来逐点分析:
         1.多读代码,网上很多好的代码,不要为了实现功能而简单的复制+粘贴,"复制+粘贴"只要会操作电脑的都会,关键学会作者的思想(非常重要啊).
这一点相信很多人应该深有体会.说句实话,要做到真的很难.特别是长一点的程序,很少新手能有耐心从头看尾.究其原因不是不愿意看,可能也实在是看不懂.其实这一点真的没有关系.长些的看不懂就先看较为简单一些的.不过在看别人的程序之前,最好还是有些基础为好,我这里指的基础,是熟悉语法然后再来看程序.说到这里,让我们看一下下面的代码,这是一个本人在网上看到的一个使用计时器的例子:
//*************************************************************************
using System;
using System.Timers;
 
class testtimer
{
    public static void Main()
    {
        Timer timer = new Timer();
        timer.Elapsed += new ElapsedEventHandler( displaytimeevent );
        timer.Interval = 1000;
        timer.Start();
        timer.Enabled = true;
 
        while ( Console.Read() == 'q' )
        {
           timer.Stop();
        }
    }
 
    public static void displaytimeevent( object source, ElapsedEventArgs e )
    {
        Console.Write("/r{0}", DateTime.Now);
    }
}
//*************************************************************************
这个例子是比较简单一个程序了.初学者到看这段代码后会先迫不及待的先copy然后再phase运行,一旦运行通过(一般都会通过,除了在字符在网页上到VS里面可能会出现空白的占位符)便也不去深究了.我在这里提出一个方法.以供参考:
第一步:这个Timer如果你是第一次看到就需要查MSDN,你会发现除了在System.Timers的命名空间下有,在System.Windows.Forms和System.Threading.Timer命名空间下面都有,在此我大概的介绍一下:
System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API  SetTimer实现的。它的缺点是计时不精确,而且必须有消息循环.
System.Timers.Timer和System.Threading.Timer非常类似,.NET  Thread  Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。System.Timers.Timer还可以应用于WinForm,完全取代上面的Timer控件。它们的缺点是没有所见即所得的功能,需要手工编码。
第二步:明白意思后.这段代码对于你的作用基本上就发挥了60%了.还有百分之四十是你的思考.有人会问这样一下简单的程序还有什么好思考的?其实不然,它的功能无非也就是延时,这种设计方式虽然简单明了,但你可以不时的问一下还有没有别的什么办法可以替代它呢?应该还有吧!于是就出来了这段代码.大家可以看一下下面这段程序:
 
//************************************************************************
using System;
using System.Threading;
 
class testtimer
{
    public static void Main()
    {
        Thread thread = new Thread(new ThreadStart(displaytimethread));
        thread.Start();
 
        if (Console.Read() == (int)('q'))
           thread.Abort();
      
    }
 
    public static void displaytimethread()
    {
        do
        {
            Console.Write("/r{0}", DateTime.Now);
        
            Thread.Sleep(1000);
        } while (true);
    }
}
//*************************************************************************
实现同样的功能却用了两种不同的方法.每个人写程序的风格都不一样.一个功能让一百个人去可能有一百种写法,你现在所需要的就是多尝试这些方法.然后从里面去找出一种最适合自己的或当前项目的.当然你更可以通过System.Windows.Forms.Timer和System.Threading.Timer来实现相同的功能.这里我就不一一列举了,之所举这个例子是希望初学者一定要学会先思考后发问,遇事多靠自己来解决
        2.多写代码,然后再不断的改进.
如果只看不练也是没有用的.程序和其它学术类的东西不一样,实际的操作也非常重要.这里讲的多写不是乱写,是有组织的写一些代码.先可以按照第一点慢慢来,然后不断的改进,这一点在上一点已经讲过了.就是不断的通过迭代法去寻找一条最好的路.因为此时你跟本不知道哪条路最好.来看一下我为大家展现的一个简单例子:
 
//*************************************************************************
 
class TestLoop
{
    public static void Main()
    {
        int num = Console.Read();
        int[] testArray = new int [100];
        for (int i = 0; i < 100; i++)
        {
            if (num < 10)
                testArray[i] = 100;
            else
                testArray[i] = 1000;
        }
    }
}
//*************************************************************************
 
很多人会问,这有什么问题吗?这是很多初学者写循环的方法.其实不然.这种方法虽然程序易读性会好一些,但是程序效率会比较低,让我们一起来看一下下面这段代码,当然它们做的是同一件事情.
 
//*************************************************************************
 
using System;
using System.Threading;
 
class TestLoop
{
    public static void Main()
    {
        int num = Console.Read();
        int[] testArray = new int [100];
        if (num < 10)
        {
            for (int i = 0; i < 100; i++)
            {
                  testArray[i] = 100;
            }
        }
        else
        {
            for (int i = 0; i < 100; i++)
            {
                testArray[i] = 1000;
            }
        }
    }
}
//*************************************************************************
这段代码可能可读性没有上一段的高,不过效率的确是要快一些,如果你不信的话,你可以把数字调大一些.效果会很更明显一些.所以从一个功能和问题延伸开来看同一件事情,你会发现真正的开发的乐趣.自然也就会乐在其中了.


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tangwei168/archive/2007/01/25/1492948.aspx

至于后面三点我也就不再累述了。上面的一些方法也只是我一己之见,你可以在以上的基础上进行改良和创新,找到适合自己的,不是有句话说得好:发明=改良+创新吗?呵呵,在这一张我们谈谈C#语言对于初学者容易搞混淆的几个地方!
1.委托与事件。委托不是C#独有的什么东西。只是在不同种语言称呼有些不同罢了。在C++里面委托其实就是函数指针。定义委托需要用到关键字delegate,先让我们来看一下CSDN里面对委托的定义: delegate 声明定义一种引用类型,该类型可用于将方法用特定的签名封装。委托实例封装静态方法或实例方法。委托大致类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。中文有点不符合我们的习惯,不过还好。这里指的方法签名就是指方法声明的类型,返回值,参量(参数),以及名称。你大致可以这样理解它:委托声明定义了一种类型,它用一组特定的参数以及返回类型来封装方法。对于静态方法,委托对象封装要调用静态方法。对于实例方法,委托对象要调用该实例上的一个方法。好的,让我们看一个实例:
 
//*************************************************************************
using System;
using System.Threading;
 
namespace ConsoleApplication6
{
    class Test
    {
        delegate void TestDelegate();//声明一个委托,对应签名函数的类型
        public static void Main()
        {
            TestDelegate tDelegate = new TestDelegate(TestFunction);//像使用类一样使用它
            tDelegate();      //调用委托,即执行TestFunction函数体内的实现
        }
        public static void TestFunction() //静态函数,请注意和声明一个很委托的签明一样,在此是静态函数的原因是因为Main函数的声明是静态的.
        {
            Console.WriteLine("This is a delegate function");
        }
       
    }
}
//*************************************************************************
 
你会发现原来委托不过如此,没有什么神秘的啊!有人会问,我直接用一个函数调用不就行了吗?为什么要用委托了。呵呵,搞得这么麻烦,如果你是这样想的话,我想你应该忍住性子看完下面这个例子:
//*************************************************************************
using System;
 
namespace ConsoleApplication6
{
    class Test
    {
        delegate void TestDelegate();//声明一个委托,对应签名函数的类型
        public static void Main()
        {
            TestDelegate tDelegate = new TestDelegate(TestFunction);//像使用类一样使用它
            tDelegate += TestFunction1;//vs2005 可以直接这样书写.
            tDelegate();      //调用委托
        }
        public static void TestFunction() //静态函数,请注意签名和声明一个很委托的签明一样
        {
            Console.WriteLine("This is a delegate function");
        }
        public static void TestFunction1()//另外的静态函数,请注意签名和声明一个很委托的签明一样
        {
            Console.WriteLine("This is a delegate function too!");
        }       
    }
}
 
 
程序运行结果:
This is a delegate function
This is a delegate function too!
 
由于程序里面使用tDelegate += TestFunction1(多点委托)所以运行tDelegate会现直接调用两个函数。当然只要你愿意,你也可以这样写:tDelegate -= TestFunction1;你也可以使用tDelegate.combine和tDelegate.remove,来实现“+=“和“==”的效果。也许你还是会非常固执的说,那我也可以接在主函数里面换上这两句话啊!
TestFunction();
TestFunction1();
还是可以运行,为什么要用委托呢?好的请看下面的代码:
using System;
 
namespace ConsoleApplication6
{
    delegate void TestDelegate();
    class Test
    {
        //声明一个委托,对应签名函数的类型
        public static void Main()
        {
            A a = new A();
            a.testDelegate();//调用委托,知道厉害了吧.
        }
      
    }
    class A
    {
        public TestDelegate testDelegate;
        public A()
        {
            testDelegate = new TestDelegate (TestFunction) + TestFunction1;//关联委托函数.
            //你也可以这么写
            //testDelegate = new TestDelegate (TestFunction);
            //testDelegate += TestFunction1;
        }
        private void TestFunction() //实例函数的签名,请注意签名和声明一个很委托的签明一样
        {
            Console.WriteLine("This is a delegate function");
        }
        private void TestFunction1()//另外的一个实例函数的签名,请注意签名和声明一个很委托的签明一样
        {
            Console.WriteLine("This is a delegate function too!");
        }       
    }
}
还没有发现其中的好处吗?呵呵。他把实例类即A,函数有机的封装在一起了,使类的暴露性更小了。更加具有可读性,把TestFunction,TestFunction1前面的修辞符加上static 看一下,照样可以运行。封装性在团队合作大型的项目中显得更加尤为重要,但是这只是委托的其中一个优点,其使用委托还可以节省很多开销, 也就是使代码效率更高.当然,还有一个委托非常重要的一点,那就是下一章的主角--事件(你可以把事件看做特殊的委托,一种特殊的表现)。它将会装委托的特质更加发挥出来。在下一章里面,你将看到委托结合事件的强大威力。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tangwei168/archive/2007/01/25/1493382.aspx

 如何学好C# 开篇浅论4

特殊的委托----事件:
今天跟大家谈谈C#事件的机制.
先来了解一下事件是什么. 学习事件之前,要把事件看成委托的一种特殊形式!这是因为面向对象在语言层是抽象的,(更高一层就是面向接口,此概念更加抽象化)所以,我们可以想象真实的世界,把现实中的一些东西放大来看本质,比如一个人饿了就需要吃饭,那么就要用很委托去关联”饿了”和”吃饭”这两个动作,一旦”饿了”就触发“吃饭“这个事件,至于如果吃什么东西,如何吃那是响应事件的内容!在Microsoft .NET世界中,不管是WEB Forms(ASP.NET)还是Windows Forms,都涉及到大量对象的事件响应及处理.现在让我们来看下一段模拟代码。
 
//**********************************************************************
using System;
 
namespace Test
{
    delegate void HungryHandler();//定义委托
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People();//小王
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作和事件
            小王.HungryAction();//激发事件
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner()//响应事件的函数,也就是响应事件该做的
        {
            Console.WriteLine("该吃饭了");//输出
        }
    }
 
    class People //实例类
    {
        public event HungryHandler HaveDinner;
        public void HungryAction()
        {
            if (HaveDinner != null)
                HaveDinner();//调用委托关联事件函数,在这是调用”小王_HaveDinner”
        }
       
    }
}
//**********************************************************************
程序输出结果为:
该吃饭了
 
这个例子应该不是你见过最复杂的代码吧。呵呵。如果上面这个例子没有问题的话,那么现在让我们一起来实现类似于winform事件的程序.当然只要有事件,委托的定义就是必须的!
 
//**********************************************************************
using System;
 
namespace Test
{
    delegate void HungryHandler(object sender, EventArgs e);//定义委托
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People("小王");//小王实例类名称
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件
            小王.HungryAction(小王.Name,new EventArgs ());//激发事件
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner(object sender, EventArgs e)//响应事件的函数,也就是响应事件该做的
        {
            Console.WriteLine(((People)sender).Name+"该吃饭了");
        }
    }
 
    class People //实例类
    {
        private string name;
        public People(string name)
        {
            this.name = name;
        }
        public event HungryHandler HaveDinner;
       
        public void HungryAction(object sender,EventArgs e)
        {
            if (HaveDinner != null)
                HaveDinner(this, e); //关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner";
        }
        public string Name
        {
            get { return name; }
        }
    }
}
//**********************************************************************
程序输出结果为:
小王该吃饭了
 
此段程序可能相对要复杂一些,但是只要是上段程序没有问题的话,仔细结合注释来看这段程序,就没有什么问题了。当然,有时候我们在windows看到一些事件不是关联的参数,有大部份都不是EventArgs类。但是有时候你却发现的事件处理函数参数还有其它的一些类,不单单只有EventArgs,如MouseEventArgs, KeyPressEventArgs, MouseEventArgs, FormClosedEventArgs,这此类其实都是从系统类EventArgs类派生出来的类。只要我们愿意或是实际的项目需要,完全可以做一个自已事件参数类,当然也要继承EventArgs啦,但这不是在此不是必须的。如果是继承窗体和控件的话,那就是必要条件。呵呵。关于继承和多态,就要看大家的需要了,如果博客里的评论反应情况了,如果反映多的话,我会在以后的章节把这几点加上去的。现在就让我们一起来对上面的程序进行扩充,来实现这一点。请看下面的程序:
//*************************************************************************************************************
 
using System;
 
namespace Test
{
    delegate void HungryHandler(object sender, HungryEventArgs e);//定义委托 ,请记住是实现事件的基础,请注意 EventArgs 已改为 HungryEventArgs
   
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People("小王");//小王实例类名称
           
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件
            小王.HungryAction(null, new HungryEventArgs("还好"));//即便传null值,照样可以响应,因为事件在HungryAction函数中已经用了this,this是用来指当前类实例对象的属性,变量和方法,不包括静态所有成员.你也可以用"小王"代替它,效果是一样的.
           
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner(object sender, HungryEventArgs e)//响应事件的函数,也就是响应事件该做的
        {
            switch (e.State)
            {
                case "很饿":
                    Console.WriteLine(((People)sender).Name + e.State + "-------该吃饭了");
                    break;
                case "还好":
                    Console.WriteLine(((People)sender).Name + e.State + "-------可以晚点吃");
                    break;
                default:
                    Console.WriteLine(((People)sender).Name + e.State + "-------不想吃");
                    break;
            }
        }
    }
 
    class People //实例类
    {
        private string name;
        private string sex;
 
       public People(string name)
        {
            this.name = name;
        }
        public event HungryHandler HaveDinner; // 定义事件
 
        public void HungryAction(object sender, HungryEventArgs e)
        {
            if (HaveDinner != null)
                HaveDinner(this, e); //请注意this的作用是返回实例的对象,关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner";
        }
        public string Name
        {
            get { return name; }
        }
    }
   
    class HungryEventArgs : EventArgs   //注意此处继承了EventArgs
    {
        private string state;
        public HungryEventArgs(string state)
        {
            this.state = state;
        }
        public string State
        {
            get { return state; }
        }
    }
}
 
程序输出结果为:
小王还好-------可以晚点吃"
//*************************************************************************************************************
好了,以上都是一些事件的基础知识,如有讲得不对的地方还请大家见谅。这段时间可能写博客的时间要少了,因为要用做UML去架构一个新的工程了。空闲时间会比较少了,当然如果我有空的话,我还是会尽快更新博客的,同时也希望读完我的文章的朋友,在评论里面留言给我,各方面的意见都可以,也可以是希望下一期的内容,我得到反馈信息后,会根据实际情况来安排,只有这样才可以使这个的博客做得更好,更贴近实际的开发。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tangwei168/archive/2007/01/26/1495050.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值