C#入门经典(第6版)阅读笔记(第一篇)(1-10)

目录

<h5>第一章 C#简介</h5>
<h5>第二章 编写C#程序</h5>
<h5>第三章 变量和表达式(注释方式)</h5>
<h5>第五章变量的更多内容</h5>
<h5>第六章 函数 *</h5>
<h5>第八章 面向对象编程简介</h5>
<h5>第九章 定义类</h5>
<h5>第十章 定义类成员</h5>


<h5>第一章 C#简介</h5>
1.1 .NET Framework的含义
1.1.1 .NET Framework是Microsoft为开发应用程序而创建的一个具有革命意义的平台。
1.1.2中间语言: 在编译使用.net framework 库的代码时,不是立即创建专用操作系统的本机代码,而是把代码编译为通用中间语言(Common Intermediate Language,CIL)代码,这些代码并非专门用于任何一种操作系统,也非专门用于C#。
1.1.3编译器:Just-In-Time(JIT)编译器的任务,他把CIL编译为专用于OS和目标机器结构的本级代码。
1.1.4程序集:在编译应用程序时,所创建的CIL代码存储在一个程序集中。程序集包括可执行的应用程序文件(.exe)和其他应用程序使用的库(.dll)。
1.1.5托管代码:在将代码编译成为CIL,再用JIT编译器将它编译为本级代码后,CLR的任务尚未完成,还需要管理正在执行的用.net framework编写的代码。托管代码最重要的一个功能是垃圾回收(garbage collection)。
1.1.6总结图:

2789632-fb5d2c4d462da2b8.png
执行过程

<h5>第二章 编写C#程序</h5>
2.1.1 第一个小程序---控制台程序HelloWorld

2789632-14570940b2d31a18.png
HelloWorld

2.1.2 第二个小程序---桌面应用---WPF application

2789632-1e30531886f42b4e.png
桌面应用---点击按钮弹窗
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Test02_WPF
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("你竟然敢点我!");
        }
    }
}


<h5>第三章 变量和表达式(由于之前学过c语言和java,部分相通的章节不会记录过多)</h5>
3.1.1注释

2789632-c5ee3bf28c5f92cb.png
注释

3.3.2注意:组成string打的字符串数量没有上限,以为他可以使用可变大小的内存。
3.3.3注意:根据约定,名称空间通常采用PascalCase命名方式。

<h5>第五章变量的更多内容</h5>

5.1.1使用Convert命令进行显示转换。
5.1.2 变量类型:结构---》就是由几个数据组成的数据结构,这些数据可能具有不同的类型----》个人感觉像是c语言中的结构体。
小例子:

2789632-b7806a60db243dcf.png
枚举与结构体的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 枚举与结构的应用
{
    //定义枚举类型
    enum orientation : byte
    { 
        north = 1,
        soutth = 2,
        east = 3,
        west = 4
    }
    //定义结构体类型
    struct route
    {
        public orientation direction;
        public double distance;
    }
    class Program
    {
        static void Main(string[] args)
        {
            route myRoute;
            int myDirection = -1;
            double myDistance;
            Console.WriteLine("1)North \n 2)South \n 3) East \n 4)West \n");
            do
            {
                Console.WriteLine("Select a direction:");
                myDirection = Convert.ToInt32(Console.ReadLine());
            }
            while((myDirection < 1) || (myDirection > 4));
            Console.WriteLine("Input a distance:");
            myDistance = Convert.ToInt32(Console.ReadLine());
            myRoute.direction = (orientation)myDirection;
            myRoute.distance = myDistance;
            Console.WriteLine("myRoute specifiex a direction of {0} and a  distance of {1}",myRoute.direction,myRoute.distance);
            Console.ReadLine();
        }
    }
}

5.1.3定义数组时注意

2789632-b1a247f63e10ddbd.png
定义数组注意

5.2.1锯齿数组---》数组的数组
5.3.1string类型变量可以看成是char变量的只读数组。为了获得一个可写的char数组,可以使用下面代码

string myString = "a string";
char[] myChar = myString.ToCharArray();

<h5>第六章 函数</h5>
6.1.1函数的定义与使用
一般采用PascaCase形式编写函数名。
函数Main()是控制台应用程序的入口点函数。
void这个关键字表明函数没有返回值。
样例:
主函数:

static void Main(string[] args)
        {
            Console.WriteLine("请输入一个整数");
            int x = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine(GetVal(x));
            Console.ReadLine();
        }

被调函数:

 static double GetVal(int n) 
        {
            if (n > 5)
            {
                return 5;
            }
            else
            {
                return 0;
            }
        }

结果显示:

2789632-def82b34de97ad1d.png
函数的定义与使用

6.1.2查看函数的参数值是否会改变
被调用函数:

2789632-65397039c3795aab.png
被调用的函数

主函数:

2789632-c38d7f64911251a5.png
主函数

结果:

2789632-42110ef626ca4cf8.png
结果

可见,从主函数,将变量通过调用函数加工后,其本身并不会做出改变。若想让其发生本质的改变,需要使用ref。如下所示:

2789632-47496d4ee09e7b8a.png
被调用的函数
2789632-c072cb0f1339695f.png
主函数调用方式
2789632-92581904e7d720b4.png
执行结果

代码:

static void ChangeParameterMethod1(int value)
        {
            value = value * 2;
            Console.WriteLine("由定义函数输出:" + value);
        }
        static void ChangeParameterMethod2( ref int value)
        {
            value = value * 2;
            Console.WriteLine("由定义函数输出:" + value);
        }
        static void Main(string[] args)
        {
            int myValue1 = 3;
            ChangeParameterMethod1(myValue1);
            Console.WriteLine("由主函数输出,查看myValue是否改变:" + myValue1);

            int myValue2 = 3;
            ChangeParameterMethod2(ref myValue2);
            Console.WriteLine("由主函数输出,查看myValue是否改变:" + myValue2);
            Console.ReadLine();
        }

6.1.3输出参数(用法与ref相同)
把未赋值的变量用作ref参数是违法的,但可以把未赋值的变量用作out参数。
另外,在函数使用out参数时,必须把它看成是尚未赋值。
6.2.1结构函数
即把函数放到结构中,可以集中处理常见任务,从而简化过程。
6.3.1重载:函数名相同,参数不同。
6.4.1委托:
委托(delegate)是一种存储函数引用的类型。主要用于事件和事件处理。委托的声明非常类似函数,但不带函数体,且要使用delegate关键字,定义了委托后就可以声明该委托类型的变量。下面我们来看一段代码,使用委托访问两个函数中的一个。个人觉得,委托就像一个已经定义好的选择器,然后根据选择去挑选所需要的函数,然后再通过委托传参。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 委托用法的练习
{
    class Program
    {
        delegate double ProcessDelegate(double param1,double param2);//委托声明(类似函数)
        static double Multiply(double param1, double param2)
        {
            return param1 * param2;
        }
        static double Divide(double param1, double param2)
        {
            return param1 / param2;
        }
        static void Main(string[] args)
        {
            ProcessDelegate process;
            Console.WriteLine("Enter 2 numbers separated with a comma:");
            string input = Console.ReadLine();
            int commaPos = input.IndexOf(',');
            double param1 = Convert.ToDouble(input.Substring(0,commaPos));
            double param2 = Convert.ToDouble(input.Substring(commaPos + 1,input.Length -1-commaPos));
            Console.WriteLine("Enter M to Multiply or D to Divide:");
            input = Console.ReadLine();
            //如果选M则调用函数Multiply否则使用函数Divide
            if (input == "M")
            {
                process = new ProcessDelegate(Multiply);
            }
            else
            {
                process = new ProcessDelegate(Divide);
            }
            Console.WriteLine("Result:{0}",process(param1,param2));
            Console.ReadLine();
        }
    }
}

执行结果:

2789632-f2e808d4d0b4fdde.png
委托的使用

<h5>第八章 面向对象编程简介</h5>
8.1.1类与对象的区别
若拿汽车比喻,类是指汽车的模板,或者用于构建汽车的规划,汽车本身是这这些规划的实例,所以可以看做对象。
8.1.2对象的生命周期
构造阶段:第一次实例化一个对象时,需要初始化该对象。这个初始化过程称为构造阶段,由构造函数完成。
正在使用阶段:正常状态
析构阶段:在删除一个对象时,常常需要执行一些清理工作,例如,释放内存,这由析构函数完成。
8.2.1封装,继承,多态之类的就不多说了,扩展两个名词:继承--》派生;父类---》基类。

<h5>第九章 定义类</h5>
9.1定义
 9.1.1抽象(abstract)类:不能实例化,只能继承。密封(sealed)类:不能继承。
 9.1.2编译器不允许派生类的可访问性高于基类。也就是说,内部类可以继承于一个公共基类,但公共基类不能继承于一个内部类。
 9.1.3如果没有基类,则被定义的类就只继承于基类System.Object(它在C#中的别名是object)。
 9.1.4必须使用逗号来分隔基类名和接口名。此处与java不同。java使用的是两个关键字,extends 和implements,C#这两个都采用的方式是“:”。
 9.1.5 类的修饰符


2789632-4232019293d3f89a.png
类的修饰符

类定义中可以使用的访问修饰符组合
  none or internal 类只能在当前工程中访问
  public 类可以在任何地方访问
 abstract or internal abstract 类只能在当前工程中访问,不能实例化,只能继承
  public abstract 类可以在任何地方访问,不能实例化,只能继承
 sealed or internal sealed 类只能在当前工程中访问,不能派生,只能实例化
  public sealed 类可以在任何地方访问,不能派生,只能实例化
9.2 System.object
 9.2.1 在利用多态性时,GetType()是一个有用的方法,允许根据对象的类型来执行不同的操作,而不是像通常那样,对所有对象都执行相同的操作。
 9.2.2抽象类和接口的相同与不同点
  相同点:

<li>都包含可以由派生类继承的成员</li>
<li>都不能直接实例化</li>

不同点:

<li>派生类只能继承一个基类,相反,类可以使用任意多个接口</li>
<li>抽象类可以拥有抽象成员和非抽象成员</li>

<li>接口成员必须都在使用接口的类上实现-----他们没有代码体</li>
<li>接口成员是公有的,抽象类的成员是私有的</li>
<li>接口不能包含字段、构造函数、析构函数、静态成员或常量</li>

9.3 结构类型
9.3.1 结构和类非常相似,但结构是值类型,而类是引用类型。代码解释:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 区分类和结构
{
    //定义一个类
    class MyClass
    {
        public int val; 
    }
    //定义一个结构,注意命名规则
    struct myStruct
    {
        public int val;
    }
    class Program
    {
        static void Main(string[] args)
        {
            //对定义的类实例化
            MyClass objectA = new MyClass();
            //此处实际上是复制了这个地址
            MyClass objectB = objectA;
            objectA.val = 20;
            objectB.val = 30;
            //对结构进行实例化
            myStruct structA = new myStruct();
            //此处赋值的是结构体的所有信息
            myStruct structB = structA;
            structA.val = 20;
            structB.val = 30;
            //输出上面的四个值
            Console.WriteLine("objectA.val = {0}",objectA.val);
            Console.WriteLine("objectB.val = {0}", objectB.val);
            Console.WriteLine("structA.val = {0}", structA.val);
            Console.WriteLine("structB.val = {0}", objectB.val);


            Console.ReadKey();
        }
    }
}

执行结果:

2789632-b07bdec59633f74d.png
类与结构

9.4 浅度复制和深度复制
浅度复制:简单的按照成员复制对象,通过拍摄呢过于System.Object的MemberwiseClone()方法;
深度复制:如果要创建成员的新实例(复制值,而不复制引用),可以实现一个ICloneable接口,以标准方式进行深度复制。如果使用这个接口,就必须实现它包含的Clone()方法。这种方式跟java中的创建多线程,实现Runnable接口创建多线程的方式挺像的。

第十章 定义类成员
10.1 成员定义

10.1.1在类定义中,也提供了该类中所有成员的定义包括字段、方法和属性。所有成员都有自己访问级别,用下面的关键字之一来定义:

  • public——成员可以由任何代码访问
  • private——成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字)
  • internal——成员只能由定义它的程序集(项目)内部的代码访问
  • protected——成员只能由类或派生类中的代码访问
    后两个关键字可以结合起来使用,protected internal,它们只能由项目中派生类的代码访问。
      10.1.2公共字段以PascalCasing形式命名,公共方法也采用PascalCasing形式命名,私有字段通常使用camelCasing来命名。
      10.1.3 如果使用了static关键字,这个方法就只能通过类来访问,不能通过对象实例来访问。也可以在方法定义中使用下述关键字:
  • virtual——方法可以重写
  • abstract——方法必须在非抽象的派生类中重写(只用于抽象类中)。
  • override——方法重写了一个基类方法(如果方法被重写,就必须使用该关键字)。&_&
  • exten——方法定义放在其他地方
    下面是一个方法重写的实例:
public class MyBaseClass
    {
        //virtual——方法可以重写
        public virtual void DoSomething()
        { 
            //Base implementation
        }
    }
    //Extends a class(MyBaseClass) and overwrite it's method
    //override——方法重写了一个基类方法(如果方法被重写,就必须使用该关键字)
    public class MyDerivedClass : MyBaseClass
    { 
        //To overwrite the method
        public override void DoSomething()
        { 
            //Drived class implementation,overrides base inplementation.
        }
    }

这个地方,如果第一个类中的方法没有加Virtual,这个方法就不可以被重写:

2789632-014d18278967988c.png
方法的重写

如果使用的override,也可以使用sealed来指定在派生类中不能对这个方法做进一步的修改。
测试代码:

 public class MyDerivedClass : MyBaseClass
    { 
        //To overwrite the method
        public override sealed void DoSomething()
        { 
            //Drived class implementation,overrides base inplementation.
        }
    }

    public class MyTestClass : MyDerivedClass
    {
        public override void DoSomething()
        { 
            //this is test to see whether the method is rewritten
        }
    }

报错显示:

2789632-e293eeba46af62d2.png
报错显示

当然,此处去除sealed,程序时可以正常运行的。
10.1.4 定义属性
  get块必须有一个属性类型的返回值,简单属性一般与私有字段相关联,以控制对这个字段的访问,此时get块可以直接返回该字段的值。
代码:

public class MyTestClass
    { 
        //Field used by prtperty
        private int myInt;
        //Property
        public int MyIntProp
        {
            get
            {
                return myInt;
            }
            set
            {
                myInt = value;
            }
        }
    }

value 等于类型与属性相同的一个值,所以如果属性和字段使用相同的类型,就不必考虑数据类型转换了。
10.1.5 this 与 base
base关键字指定.NET实例化过程使用基类中具有指定参数的构造函数。
this这个关键字指定调用指定的构造函数前,.net实例化过程对当前类使用非默认的构造函数。
如果没有给构造函数指定构造函数初始化器,编译器就会自动添加base()。
this关键字与base一样,this也可以用在类成员内部,且该关键字也引用对象实例。只是this应用的是当前的对象实例(即不能在静态成员中使用this关键字,因为静态成员不是对象实例的一部分)。

微信公众号:


2789632-004f4c10ad78329c.png







2789632-3b18269684ea9294.png
公众号.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值