C#学习笔记(一)

创建.NET应用程序的步骤:

1)使用某种.NET兼容语言编写应用程序代码


2)把代码编译为CIL,存储在程序集中


3)执行代码时,使用JIT编译器将代码编译为本机代码


4)在托管的CLR环境下运行本机代码,以及其他应用程序或进程



用字符串表示带路径的文件名,字符串中会带有大量的斜杠,例如:"c:\\Temp\\MyDir\\MyFile.doc",可以在字符串前加一个@符号,这样对于引号,双引号,斜杠等符号就不用在转义了,例如:@"c:\Temp\MyDir\MyFile.doc"


把字符串转换成枚举变量不能使用简单的类型转换,需要用一个特殊的语法:(enumerationType)Enum.Parse(typeof(enumerationType), enumString);


以下方式声明数组:

Type[] name;

 这样只是定义了一个数组类型的变量,并没有指定数组的大小,数组中也没有内容,可以在定义的时候初始化,如:


 也可以先定义数组,然后再初始化,如:

int[] myIntArray;
myIntArray = new int[5] { 5, 9, 10, 2, 99};
如果定义数组时没有初始化,那么数组中的所有元素都有同一个默认值,对于数值类型来说,其默认值是0,初始化元素的数量必须与数组的长度一致,不能只初始化部分元素,这与C++是不一样的

二维数组采用如下方式申明:

int[,] myIntArray;

声明时可不指定任何的维度,因为C#限制初始化列表必须与数组的长度一致,所以根据初始化列表就可以确定数组的长度,但必须采用分段初始化的方式,如:

            int[,] myIntArray;
            myIntArray = new int[,] { { 1, 2 }, { 2, 3 } };

申明数组的数组,即数组中的每个元素都是一个数组,语法如下:

int[][] jaggedIntArray;

数组的数组有两种初始化方式:

一。依次把每个元素初始化为数组

jaggedIntArray = new int[2][];
jaggedIntArray[0] = new int[3];
jaggedIntArray[1] = new int[4];

二。在定义的时候初始化

jaggedIntArray = new int[3][]{new int[]{1, 2, 3}, new int[] {1}, new int[] {1, 2}};

int[][] jaggedIntArray = new int[3][]{new int[]{1, 2, 3}, new int[] {1}, new int[] {1, 2}};

C#有一种特殊的函数参数,这种参数只能出现在参数列表的最后一个,叫做参数数组,它有params关键字定义,定义的形式为:

params type[] name

调用方式可以采用

functionname(var1, var2....,varn);

唯一的限制是var等一系列变量必须类型相同并且是type类型的


C#的函数参数默认为值参数,如果需要使用引用参数,需要在函数参数前加上ref关键字,同时在调用函数的地方,也要在参数前加上ref关键字,例如:

        int number = 2;
        Func(ref number);
        static void Func(ref int number)
        {
            number *= 2;
        }

C#可以使用输出参数,需要在函数参数前加上out关键字,同事在调用函数的地方,也要在参数前加上out关键字,例如:

        int MaxValue;
        Func(ints, out MaxValue);
        static void Func(int[] ints, out int MaxValue)
        {
            MaxValue = ints[0];
            foreach (int i in ints)
            {
                if (i > MaxValue)
                {
                    MaxValue = i;
                }
            }
        }

注意;输出参数可以是未初始化的,即使是经过初始化的,在使用输出参数时,也需要将它看作是未初始化的


函数委托类似与C++中的函数指针,示例如下:

        delegate int OperationFunc(int a, int b);

        static void Main(string[] args)
        {
            OperationFunc function = new OperationFunc(Add);
            int iResult = 0;
            iResult = function(1, 2);
            Console.WriteLine(iResult);
            function = new OperationFunc(Mulit);
            iResult = function(2, 3);
            Console.WriteLine(iResult);

            Console.ReadKey();
        }

        static int Add(int a, int b)
        {
            return a + b;
        }

        static int Mulit(int a, int b)
        {
            return a * b;
        }
注意,委托定义中是没有static的


Debug.WriteLine()和Trace.WriteLine()都是用于向IDE的输出窗口输出内容,用于程序运行时显示信息,区别在于前者只在debug模式下生效,而后者在debug和release模式下都生效,这些信息也可以在满足某些条件的情况下才输出,分别对应Debug.WriteLineIf()和Trace.WriteLine If()这两个函数,但参数1中的表达式结果为真,则输出要显示的信息


在使用类静态成员变量前,需要对静态成员变量进行初始化,尽管可以在声明时进行初始化,但有时需要比较复杂的初始化,可以使用静态构造函数执行这种初始化任务,一个类只能有一个静态构造函数,该构造函数不能有访问修饰符,也不能带有任何参数,静态构造函数不能直接调用,只能在下述情况下执行:

  1. 创建包含静态构造函数的类实例时
  2. 访问包含静态构造函数的类的静态成员时
示例:

    class MyClass
    {
        public static int m_i;

        static MyClass()
        {
            Console.WriteLine("静态构造函数被调用");
            m_i = 5;
        }
    }


静态类只能包含静态成员,不需要示例构造函数,静态类可以有一个静态构造函数,示例:

{
    static class MyStaticClass
    {
        static MyStaticClass()
        {

        }

        public static void func()
        {

        }

        public static int m_i;
    }

默认情况下,类申明是内部的,即只有当前项目中的代码才能访问它,还可以指定类是公共的,可以由其他项目中的代码来访问,为此,要使用关键字public来进行类声明,还可以指定类是抽象的(abstract,不能实例化,只能继承,可以有抽象成员)或密封的(sealed,不能继承)。


在C#的类定义中,只能有一个基类,如果继承了一个抽象类,就必须实现所继承的所有抽象成员。编译器不允许派生类的可访问性高于基类,也就是说,内部类可以集成于一个公共基类,但公共类不能继承于一个内部类。


申明接口的方式与声明类相似,但使用的关键字是interface,而不是class,访问修饰符关键字public和internal的使用方式是相同的,与类一样,接口也默认定义为内部接口,所以要使接口可以公开访问,必须使用public关键字,不能在接口中使用关键字abstract和sealed,因为这两个修饰符在接口定义中是没有意义的。


无论在派生类上使用什么构造函数,除非明确指定,否则就是用基类的默认构造函数,如需要调用基类的其他构造函数,可以把代码放在方法定义的冒号后面,base关键字用于表示基类,this关键字用于表示当前类,例如:

        public Derived() : base(1)
        {}

        public Derived(int i) : this(1, 2)
        {}

        public Derived(int i, int j)
        {}


接口和抽象类:

相似点

  • 抽象类和接口都包含可以由派生类继承的成员
  • 接口和抽象类都不能直接实例化,但可以申明这些类型的变量
区别

  • 派生类只能集成一个基类,类可以使用任意多个接口
  • 抽象类可以拥有抽象成员和非抽象成员,接口成员必须在使用接口的类上实现
  • 接口不能包含字段,构造函数、析构函数、静态成员或常量

类与结构很相似,但类是应用类型,而结构是值类型,比如:将一个类对象赋值给另一个类对象,这两个类对象将指向同一块内存,修改一个对象,另一个对象的值也会改变,而将一个结构变量赋值给另一个结构变量,这两个结构变量只是内容一样,指向两块不同的内存



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值