zoukankan      html  css  js  c++  java
  • 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} ",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;
        }
      }
  • 相关阅读:
    子网划分详解
    USACO range
    USACO shopping
    USACO fence
    USACO Spinning Wheels
    USACO butter
    USACO msquare
    USACO Feed Ratios
    USACO Stringsobits
    USACO Factorials
  • 原文地址:https://www.cnblogs.com/praybb/p/7650163.html
Copyright © 2011-2022 走看看