C#高级编程笔记 (1至6章节)数组,类/方法/泛型

2.3变量

var 类型推断

type 类的分类 如:type nametype = name.GetType(); //取变量name的类型

const 常量  const int painame = 3.1415

char 是字符类型 string是字符串类型

2.5语句

选择语句:switch(变量){case 常量值1:语句1 break;…………;default 常量值n:语句2 break;}

二个值相同语句时:switch(变量){case 常量值1:case 常量值1:语句1 break;…………;default 常量值n:语句2 break;}

wile 循环一般用在不知道循环多少次的情况下

do…wile 是先循环后判断

foreach() 遍历

goto 跳转语句 goto pray;语句1;…………;pray: 语句n; ///直接跳过语句1执行语句n (大多情况下不允许用慎用)

break 跳出循环体

continue 跳过当次循环(非跳出循环体)

2.6枚举型

Main()
        {
            TimeOfDay time = (TimeOfDay)Enum.Parse(typeof(TimeOfDay), "afternoon",true); //从字符串对应的值,参数3区分大小写
            Console.WriteLine((int)time);
            TimeOfDay time2 = TimeOfDay.Evening;
            Console.WriteLine((int)time2);//输出为2
        }
        public enum TimeOfDay
        {
            morning = 0,
            Afternoon = 1,
            Evening = 2,
        }

2.7空间名称

testpray.testclass.Class1.***()
namespace testpray
{
    namespace testclass { 
    class Class1
    {}}}

2.8给Main()方法传递参数

static int Main(string[] args)
        {
            for (int i = 0; i < args.Length; i++)
            {
                Console.WriteLine(args[i]);
            }
            return 0;
        }
//在CMD下运行程序 test /a /r /e  ,a、r、e为参数

2.10控制台

Console.WriteLine("{0,4:C2}\n",i,} // 0表示索引值(对应变量I),4表示宽度(正直表示右对齐,负值表示左对齐,C2表输出精度后2位的货币,)

C 货币
D 十进制
E 科学计数法
F 小数点位数
G 普通格式 (只显示前n个有效数字)
N 显示千分制     12543.234      n2        12,543.12
p 百分数      0.52123           p2                 52.12%
X 十六进制    

2.12 C#预处理指令

#define  名称符号  (声明存在这个符号,用于调试)         #undef 名称符号 (删除符号)

#if  名称符号 (在前面的#define时才会执行)    #

3.3 类

类的参数,如果是引用类型(如数组或类)传递给方法,对应的方法会改变数组中的值,而新值会反射在原数组里.

ref 参数,在值参数前加入ref 其方法对参数的改变会在原始对象中体现!(调用时也要在参数上添加 ref)

out 参数,传递时变量可以不初始化,(调用时也要在参数前加 out)

命名参数,调用时可 test(i:32,98);

可选参数,必须在是方法定义的最后的参数(net4) 例:void test(int i,int n = 10) {…} //多个可选参数时可与命名参数指定参数!

方法的重载

属性的访问修饰符如: public name{get{} private set{}}

(构造函数???)

struct 定义一个结构体 如struct 名称 {}    注:结构是值类型

partial 部分类 ,在多个文件中存放有方法和属性  例: partial class name{}

3.10 扩展方法

扩展方法是静态方法  新建一个静态类,然后其内容中添加:

public static void AddToAmount(this 类名 参数1,扩展的方法) {参数1.Amount += 扩展的方法 }

4.3.1虚方法 (用于多态性)

virtual 关键字,例 基类: public virtual string Testprint(){} 派生类:public override string Testprint()注:字段与静态函数不能声明为virtual

using System;
namespace PolymorphismApplication
{
   class Shape 
   {
      protected int width, height;
      public Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      public virtual int area()
      {
         Console.WriteLine("父类的面积:");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): base(a, b)
      {

      }
      public override int area ()
      {
         Console.WriteLine("Rectangle 类的面积:");
         return (width * height); 
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): base(a, b)
      {
      
      }
      public override int area()
      {
         Console.WriteLine("Triangle 类的面积:");
         return (width * height / 2); 
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("面积: {0}", a);
      }
   }  
   class Tester
   {
      
      static void Main(string[] args)
      {
         Caller c = new Caller();
         Rectangle r = new Rectangle(10, 7);
         Triangle t = new Triangle(10, 5);
         c.CallArea(r);
         c.CallArea(t);
         Console.ReadKey();
      }
   }
}
实例:虚方法的多态性

 

4.3.2隐藏方法要隐藏基类时要用New

调用基类的方法 base.基类函数名()

抽象类与方法   必须在派生类中重写,   理解用于防漏写方法 修饰符:abstract

密封类与方法  例 sealed class name{} 对于类表示不能继承,  对于方法表示不能重写

注:应用于方法或属性时,sealed 修饰符必须始终与 override 结合使用。

4.36 带参数的构造函数  this()表示当前法

4.5 接口 关键字:interface   例  public interface IDisposable{} 有点类类似抽象类 接口的应用统一接口 相关介绍

派生的接口例:(如不理解请查看108页与相关介绍)

public interface ITransferBankAccount : IBankAccount
    {
        bool TransferTo(IBankAccount destination, decimal amount);
    }

5.1.1泛型 相关介绍与用法可参考

5.3.2约束 where T :struct 对于结构约束,类型T必须是值类型

5.4.1 协变与抗变 相关资料 相关理解

        static void Main(string[] args)
        {
            //协变
            IIndex<Rectangle> rectangles = RectangleCollection.GetRectangles();
            IIndex<Shape> shapes = rectangles;
            for (var i = 0; i < shapes.Count; i++)
            {
                Console.WriteLine(shapes[i]);
            }
            Console.ReadKey();
        }
    }
    public class Shape
    {
        public double Width { get; set; }
        public double Height { get; set; }

        public override string ToString()
        {
            return string.Format("Width: {0}, Height: {1}.", Width.ToString(), Height.ToString());
        }
    }
    public class Rectangle : Shape
    {

    }

    public interface IIndex<out T>
    {
        T this[int index] { get; }
        int Count { get; }
    }
    public class RectangleCollection : IIndex<Rectangle>
    {
        private readonly Rectangle[] _data = new Rectangle[3]
                                 {
                                     new Rectangle{Height = 2,Width = 5},
                                     new Rectangle{Height = 3,Width = 4},
                                     new Rectangle{Height = 4,Width = 5},
                                 };

        public static RectangleCollection GetRectangles()
        {
            return new RectangleCollection();
        }

        public Rectangle this[int index]
        {
            get
            {
                if (index < 0 || index > _data.Length)
                    throw new ArgumentOutOfRangeException("index");
                return _data[index];
            }
        }

        public int Count { get { return _data.Length; } }
协变实例

6.4锯齿数组

int[][] =new int[3],[]

6.5Array类 如果数组元素超出整数取值范围,可以做用longlength属性来获取元素大小,,,Rank属性-数组的维数

6.5.1创建数组 Array1.CreateInstance(typeof(int),5)

设置数组元素Array1.SetValue(元素值,下标); 获取元素Array1.GetValue(下标);

6.5.2复制数组 因数组为引用类型,所以不能直接用等号,如果数组的元素为值类型,复制用 Array2=(int[]) Array1.Clone(); 注意如果数组的元素为引用类型则只复制引用,修改其只一个会改变另一个对象,如要深层副本,则必须迭代数组并创建新对象。

6.5.3数组排序 简单类型int与String可直接Array.Sort(数组)排序,如自定义类, 要使之实现IComparable<类>接口的Compareto方法,如下:

public int CompareTo(Person other)
        {
            if (other == null) throw new ArgumentNullException("other"); 

            int result = this.LastName.CompareTo(other.LastName);
            if (result == 0)
            {
                result = this.FirstName.CompareTo(other.FirstName);
            }

            return result;
        }

6.6.2 ArraySegment<T>

static void Main()
        {
            int[] ar1 = { 1, 4, 5, 11, 13, 18 };
            int[] ar2 = { 3, 4, 5, 18, 21, 27, 33 };
            //分隔ar1的索引0后的3个元素,与ar2的索引3后的3个元素.
            var segments = new ArraySegment<int>[2]  {new ArraySegment<int>(ar1, 0, 3), new ArraySegment<int>(ar2, 3, 3)};
            var sum = SumOfSegments(segments);
            Console.WriteLine("sum of all segments: {0}", sum);
            Console.ReadKey();
        }

        static int SumOfSegments(ArraySegment<int>[] segments)
        {
            int sum = 0;
            foreach (var segment in segments)
            {
                for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
                    //i取的是数组的原数组下标值!即ar1与ar2的下标
                {
                    sum += segment.Array[i];
                }
            }
            return sum;
        }

如数组段中改变了数组,则原数组也会改变!

6.7.3yield语句(yield是一个语法糖)

1迭代集合不同方式

class Program
{
    static void Main()
    {
        var titles = new MusicTitles();
        foreach (var title in titles.Subset(2, 2))
        {
            Console.WriteLine(title);
        }
    }       
}
public class MusicTitles
{
    string[] names = { "Tubular Bells", "Hergest Ridge", "Ommadawn", "Platinum" };
    public IEnumerable<string> Subset(int index, int length)
    {
        for (int i = index; i < index + length;
                  i++)
        {
            yield return names[i];
        }
    }
}

2用yieid return 返回枚举器

static void Main()
    {
      var game = new GameMoves();
      IEnumerator enumerator = game.Cross();
     while (enumerator.MoveNext())
      {
       enumerator = enumerator.Current as IEnumerator;
      }
           Console.ReadLine();
    }

 public class GameMoves
  {
    private IEnumerator cross;
    private IEnumerator circle;
    public GameMoves()
    {
      cross = Cross();
      circle = Circle();
    }
    private int move = 0;
    const int MaxMoves = 9;
    public IEnumerator Cross()
    {
      while (true)
      {
        Console.WriteLine("Cross, move {0}", move);
        if (++move >= MaxMoves)
          yield break;
        yield return circle;//下一次为circle方法
            }
    }
    public IEnumerator Circle()
    {
      while (true)
      {
        Console.WriteLine("Circle, move {0}", move);
        if (++move >= MaxMoves)
          yield break;
        yield return cross;//下一次为Cross方法
            }
    }
  }

6.8元组

var result = Divide(5, 2);
    Console.WriteLine("result of division: {0}, reminder: {1}, resum:{2}", result.Item1, result.Item2, result.Item3);
    public static Tuple<int, int,int> Divide(int dividend, int divisor)
    {
      int result = dividend / divisor;
      int reminder = dividend % divisor;
            int resum = dividend + divisor;
      return Tuple.Create<int,int,int>(result, reminder, resum);

6.9结构比较

通过类IStructuralEquatable接口实现比较内容与引用!

对于IstructuralEquatable接口定义的Equals()方法,它的第一个参数是object类型,
       第二个参数是IEqualityComparer类型。调用这个方法时,通过传递一个实现了IEqualityComparer<T>的对象,就
      可以定义如何进行比较。通过EqualityComparer<T>类完成IEqualityComparer的一个默认实现。这个实现检查类型是否
      实现了IEquatable接口,并调用IEquatable.Equals()方法(即这里的Person类的Equals方法)。如果该类型没有实现IEquatable,就
      调用Object基类中的Equals()方法进行比较。
                  if ((persons1 as IStructuralEquatable).Equals(
                persons2, EqualityComparer<Person>.Default))
       单步调试上面这行代码时,由于persons1和persons2共有三个元素
       所以比较函数会进行三次(注意:会被执行三次),由于两个数组中第三个元素的FirstName
       不相同,所以返回内容不相同的结果
注意:如果两个数组的元素个数不相等,则直接返回不相等,不会调用Person类的Equals比较方法

static void Main()
    {
      var janet = new Person { FirstName = "Janet", LastName = "Jackson"};
      Person[] persons1 = { new Person { FirstName = "Michael", LastName = "Jackson" }, janet };
      Person[] persons2 = { new Person { FirstName = "Michae2", LastName = "Jackson" }, janet };
            Console.WriteLine(janet.ToString());
            Console.ReadLine();
      if (persons1 != persons2) { 
        Console.WriteLine("不相同的引用");
            }
            if (!persons1.Equals(persons2))
        Console.WriteLine("等于返回false -不相同的引用");
      if ((persons1 as IStructuralEquatable).Equals(persons2, EqualityComparer<Person>.Default))
        Console.WriteLine("相同的内容");
      }

public class Person : IEquatable<Person>
  {
    public int Id { get; private set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0}, {1} {2}", Id, FirstName, LastName);
    }
   public bool Equals(Person other)
    {
      if (other == null)
        return base.Equals(other);

      return this.FirstName == other.FirstName && this.LastName == other.LastName;
    }
  }
posted @ 2017-10-20 16:01  天祈笨笨  阅读(294)  评论(0)    收藏  举报