一  c#数组

 class Program
    {

        static void Main(string[] args)
        {
           //实例化对象
            Student s = new Student(1, "zixuan") { Score = 100 };
             Console.WriteLine("{0} {1} {2}\n", s.Id,s.Name, s.Score);
             int[] array1 = new int[5];
             int[] array2 = new int[] { 1, 1, 2, 3, 5 };
             int[] array3 = { 1, 1, 2, 3, 5 , 2, 1};
             array2.CopyTo(array1, 0);
            //数组的拷贝
             Array.Sort(array3);
            //数组排序
        }
    }

 

 

查看帮助文档知,数组的CopyTo()方法第一个参数是一个数组,第二个是索引值(从哪个位置开始拷贝)

 

打印数组



        static void Main(string[] args)
        {
           //实例化对象
            Student s = new Student(1, "zixuan") { Score = 100 };
             Console.WriteLine("{0} {1} {2}\n", s.Id,s.Name, s.Score);
             int[] array1 = new int[5];
             int[] array2 = new int[] { 1, 1, 2, 3, 5 };
             int[] array3 = { 1, 1, 2, 3, 5 , 2, 1};
             array2.CopyTo(array1, 0);
            //数组的拷贝
             Array.Sort(array3);
            //数组排序
             for (int i = 0; i < array1.Length; i++)
                 Console.Write("{0}", array1[i]+"\n");
            //打印输出
             Console.WriteLine();

            //foreach循环
             foreach (var n in array3)
                 Console.Write("{0}", n+"\n");
             Console.WriteLine();

        }
    }

 

 二 字符串

C# 支持两种形式的字符串:常规字符串和原义字符串。


在原义字符串中,分隔符之间的字符逐字解释,不处理简单转义序列以及十六进制和Unicode 转义序列。原义字符串可以跨多行。

class Program
{
    static void Main(string[] args)
    {
        string s1 = "d:\\temp";   //常规字符串
        string s2 = @"d:\temp";  //原义字符串
        Console.WriteLine("{0}", s1);
        Console.WriteLine("{0}", s2);
        Console.WriteLine("{0}", s1.Equals(s2));
        Console.WriteLine("{0}", s1 == s2);
        Console.WriteLine("{0}", s1[4]); // 可使用索引器访问串的的每一个字符
     Console.WriteLine("{0}", s1[0]);
            //字符串索引,从0开始索引
            foreach (var n in s2)
                Console.Write("{0}", n);

    }
}

三。索引器

索引器用于以更便捷的方式访问对象中包含的成员数组或集合。索引器与属性类似,不同的是索引器的访问是带参的。


例1:用整数作为下标

​

 class Student {
        private double[] _scores = new double[2];
        public int Id { get; set; }
        public string Name { get; set; }       
 
        public Student(int id, string name) {
            Id = id;
            Name = name;
        }
         public double this[int index] {
            get { return _scores[index]; }
            set { _scores[index] = value; }
        }
    }


class Program {
        static void Main(string[] args) {
            Student s = new Student(1, "zixuan");
            s[0] = 68;
            s[1] = 89;
            Console.WriteLine("{0} {1} {2} {3}\n", s.Id, s.Name, s[0],s[1]);
        }
    }

[点击并拖拽以移动]
​

 

例2: 用字符串做下标

 class Student {
        public int Id { get; set; }
        public string Name { get; set; }
        public Dictionary<string, double> Scores { get; set; }
   //字典索引
        public Student(int id, string name) {
            Scores = new Dictionary<string, double>();
            Id = id;
            Name = name;
        }
    public double this[string index] {
            get { return Scores[index]; }
            set { Scores[index] = value; }
        }
    }

  class Program {
        static void Main(string[] args) {
            Student s = new Student(1, "zixuan");
            s.Scores.Add("English", 89);  //方式1
            s["Math"] = 99;  //方式2
            Console.WriteLine("{0} {1} {2} {3}", s.Id, s.Name, s["English"], s["Math"]);
        }
    }
}

 

 

4.集合

4.1 System.Collections 命名空间
    传统集合


4.2 System.Collections.Generic 命名空间
    泛型集合

五:委托和Lambda表达式

在C/C++中,通过函数指针可将函数的入口地址传递给另一个函数。


C#中使用委托(delegate)来提供相同的功能,它将方法作为对象封装起来,允许在运行时绑定一个或多个方法。委托和类一样属于引用类型。


Lambda表达式与委托直接相关。当参数是委托类型时,就可以使用Lambda表达式实现委托的方法。

5.1   定义委托类型和委托的实例化

使用delegate关键字来声明委托数据类型

  public delegate bool ComparisonHandler(int first, int second);
 
    class BanJi {
        int[] scores;
 
        public BanJi() {
              scores = new int[] { 67, 33, 66, 99, 87, 11 };
        }

 public void SortScore( ComparisonHandler  ComparisonMethod) {
            int temp;
            int flag = 1; //当flag为0则停止排序
            for (int i = 1; i < scores.Length; i++) { //i表示趟数,最多n-1趟
                flag = 0; //开始时元素未交换
                for (int j = scores.Length - 1; j >= i; j--)
                    if (ComparisonMethod(scores[j] , scores[j - 1])) { //发生逆序    
                        temp = scores[j];
                        scores[j] = scores[j - 1];
                        scores[j - 1] = temp;
                        flag = 1;
                    }        //交换,并标记发生了交换
                if (flag == 0)
                    return;
            }
        }
 public void PrintScore() {
            foreach (int s in scores)
                Console.Write("{0} ", s);
            Console.WriteLine();
        }
    }

class Program {
        static bool Compare1(int first, int second) {
            return first > second;
        }
 
        static bool Compare2(int first, int second) {
            return first < second;
        }

       static void Main(string[] args) {
            BanJi b = new BanJi();
           ComparisonHandler compare = Compare1;
            b.SortScore(compare);
            b.PrintScore();
          //传入一个比较器
            b.SortScore(Compare2);
            b.PrintScore();
        }
    }
}

   

 5.2    匿名方法

所谓匿名方法就是没有实际方法声明的委托实例,其定义直接内嵌在代码中。

static void Main(string[] args) {
BanJi b = new BanJi();
//匿名方法
ComparisonHandler comparisonMethod = delegate(int first, int second) {
    return first > second;
};
b.SortScore(comparisonMethod);
b.PrintScore();

b.SortScore(delegate(int first, int second) {
    return first < second;
});
b.PrintScore();           
}

5.3 Lambda表达式

 

Lambda表达式是比匿名方法更加简洁的一种匿名函数语法。分为两种类型:语句Lambda和表达式Lambda。

 class Program {
        static void Main(string[] args) {
            BanJi b = new BanJi();
            b.SortScore((int first, int second) => {
                    return first > second;
            });  //语句Lambda
 
            b.SortScore((first, scond) => {
                return first > scond;
            }); //只要编译器能推断出类型,就允许省略参数类型
 
            b.SortScore((first, scond) => first > scond); //表达式Lambda
            b.PrintScore();           
        }
 }

5.4 多播委托

 

可以将多个方法绑定到同一个委托,即多播委托。当调用这个委托时,将依次调用其所绑定的方法。
通过重载运算符“+=”向委托添加方法,用“-=”取消绑定。


    class Student {
        public delegate void ScoreChangeHandler(int score);
         //声明委托
        private int _score;
        public ScoreChangeHandler OnScoreChange;
        public string Name { get; set; }
        public int Score {
            get { return _score; }
            set {
                if (_score != value) {
                    _score = value;
                    OnScoreChange(_score);
                }
            }
        }
    }
   class Mother {
        public void OnScoreChanged(int score) {
            if (score < 60)
                Console.WriteLine("失败乃成功之母!");
            else if (score > 90)
                Console.WriteLine("再接再厉!");
        }
    }
 class Father {
        public void OnScoreChanged(int score) {
            if (score < 60)
                Console.WriteLine("你在想屁吃!");
            else if (score > 90)
                Console.WriteLine("还可以!");
        }
    }

     class Program {
        static void Main(string[] args) {
            Student son = new Student();
            Father dad = new Father();
            Mother mom = new Mother();
            son.OnScoreChange += dad.OnScoreChanged;
          // 添加方法到委托
            son.OnScoreChange += mom.OnScoreChanged;
            son.Score = 60;
        }
    }

5.5 事件

事件是类的主要成员之一,是一个对象用来通知某一动作的发生而发出的消息。在面向对象程序设计中,消息传递都通过事件触发来实现的。

包含事件成员的类型可以提供以下功能:
①其他对象可以在事件上注册处理方法;
②删除事件处理方法的注册;
③拥有事件的对象可以维护注册到事件上的对象,并在某些动作发生时通知这些对象。


.NET Framework中的事件机制是建立在委托模型基础上的。用关键字event来声明事件,事件实质上一个封装得更好的委托对象。

class ScoreEventArgs : EventArgs { 
      //声明事件参数类
        public readonly int score;
        public ScoreEventArgs(int score) {
            this.score = score;
        }
    }
 class Student {
        public string Name { get; set; }
        private int _score;
 
        public delegate void ScoreChangeEventHandler(Object sender, ScoreEventArgs e);       //声明委托
        public event ScoreChangeEventHandler ScoreChanged; //声明事件
 
        protected virtual void OnScoreChanged(ScoreEventArgs e) {
            if (ScoreChanged != null) {
                ScoreChanged(this, e);
           //定义响应事件的操作
            }
        }
     public int Score {
            get { return _score; }
            set {
                if (_score != value) {
                    _score = value;
                    ScoreEventArgs e = new ScoreEventArgs(Score);
                    OnScoreChanged(e);
                }
            }
        }
}
class Mother {
        public void OnScoreChanged(Object sender,ScoreEventArgs e) {
            if (e.score < 60)
                Console.WriteLine("失败乃成功之母!");
            else if (e.score > 90)
                Console.WriteLine("再接再厉!");
        }
    }
 
    class Father {
        public void OnScoreChanged(Object sender, ScoreEventArgs e) {
            if (e.score < 60)
                Console.WriteLine("你在想屁吃!");
            else if (e.score > 90)
                Console.WriteLine("奖奖奖!");
        }
    }
    class Program {
        static void Main(string[] args) {
            Student son = new Student();
            Father dad = new Father();
            Mother mom = new Mother();
            son.ScoreChanged += dad.OnScoreChanged;
            son.ScoreChanged += mom.OnScoreChanged;
            son.Score = 50;
        }
    }

5.6 可空类型

 

对于一个类型,如果既可以给它分配一个值,也可以给它分配 null(表示没有任何值),我们就说这个类型是可空的。 因此,可以为 null 的类型可表示一个值,或表示不存在任何值。


例如,类似 String 的引用类型就是可以为 null 的类型,而类似 Int32 的值类型不是可以为 null 的类型。

Nullable是.NET 2.0中新提供的一种用于标明一个值类型是否可以为空的技术。


Nullable<T> 结构支持将值类型扩展为可以为null,但不支持在引用类型上使用,因为引用类型本身就是可空的。

T?:表示可空类型,就是一种特殊的值类型,它的值可以为null。
   语法 T? 是 System.Nullable<T> 的简写,此处的 T 为值类型,这两种形式可以互换。


T??:用于判断前一个操作数是否为null,如为null则返回后一个操作数,否则返回前一个操作数。

public static class Program
{
    public static void Main(string[] args)
    {
        int? a = 3;
    //设置a可空
        Console.WriteLine(a);
        Console.WriteLine(a.HasValue);
 
        a = null;
        Console.WriteLine(a.HasValue);
        if (a == null)
            Console.WriteLine("null");
 
        int b = a ?? 0;
        Console.WriteLine(b);
 
        int c = a.GetValueOrDefault();
        Console.WriteLine(c);
    }
}