• C#基础知识整理


          年时,北风吹雁雪纷纷,一条秋裤冻上头。冷的连手都懒得动,就随便翻翻书,也没有更新博客,如今年已过,开始投入到正常的工作状态中,趁现在需求还没有来,把C#基础知识梳理一下,其实一直以来就想这样做的,对于程序员来说,手指一点,各种详细的资料就出来了,但并不是自己的,有些基础的点总是隔一段时间就忘记,或者说自己压根就没有真正理解过,不管怎样,好记性不如烂笔头,先写再说,一次整理一部分,慢慢积累起来。

      

         1.C#定义常量的方式  const定义静态常量,申明时需要初始值,一旦申明不可改变。

         2.构造函数与类名相同,可重载,可带参数,创建该类对象时,自动调用。在调用其他构造函数的时候 public xx():this()       

         3.数据类型(装箱: 值类型->引用类型   拆箱:引用类型->值类型)

           值类型:int、char、bool、枚举、结构 直接存储在栈里

           引用类型:string、数组、类、接口、委托、对象  栈里面存储地址,实际上对象存储在堆里

           (PS  队列:先进先出  栈:后进先出)

         4. 类型转换

            隐式转换(所有情况下成立)

            显示转换(部分情况下成立,包括convert在内的强制转换)

         5. 引用传递

             ref : 有进有出,调用前需要赋初始值

             out: 只出不进,调用前不需要赋初始值

    为什么要用到引用参数?个人理解:当需要在A方法中处理过的B参数值,但该方法又不返回B参数时,就可以通过引用参数来解决此问题。

        class Program
        {
            //引用传值,最后都会改变原来的值
            static void Main(string[] args)
            {
                Program p = new Program();
                int outtemp;           //只需定义变量
                p.MyOut(out outtemp);
                int refbb = 8;      //必须赋初始值
                p.MyRef(ref refbb);               
                Console.WriteLine(outtemp);  // out 5
                Console.WriteLine(refbb);    // ref 6    
                Console.ReadKey();
            }
            public void MyOut(out int a) 
            {
                a = 5;
            }
    
            public void MyRef(ref int b) 
            {
                b = 6;
            }
        }

         6.静态和实例成员的区别?

             实例成员只能在类的对象实例上使用,静态成员只能通过类定义使用

         7.委托是个什么玩意?

           关于委托,网上资料一大把,包括学校的教材所写, 基本上都是举语言问候的例子。其实这个例子是完全不适合的,没有任何卵用,甚至起到了副作用

           随便摘抄其中千篇一律的某点,使用委托极大增加了扩展性,可维护性,摒弃之前的if/Switch 用法,我就纳闷了,例子和结论完全不沾边,怎么得出的鬼结论。

    之前Switch语法,直接传入参数name,然后调用对应的语言问候方法。这里接受到的name是不确定其值的,所以必须要进行一个判断。或者采用继承、实例。

    然后语言问候的例子中,直接传入name、问候方法两参数。我就纳闷了你怎么知道要调用这个问候方法?采用委托链?这里实际上是没有任何意义的。

     其实真正在项目中用到的委托,多数是结合事件一起用的。

        public delegate void myFirstDele(int a, int b);   // 定义一个委托类型
        class Program
        {
            //(PS:Calculation 类中是实现传入两参数的加/减运算)
            static void Main(string[] args)
            {
                //委託方法一: 直接將方法賦值給委託變量,再給委託變量賦參數
                //myFirstDele add = Calculation.Addcount;
                //myFirstDele Substra = Calculation.substract;
                //add(10, 10);
                //Substra(10, 10);
    
                //委託方法二: 写一个中間方法,调用中间方法,将实现的方法当做参数来传递
                Calculat(10,10,Calculation.Addcount);
                Calculat(10, 10, Calculation.substract);
                Console.ReadKey();         
            }   
      
            //中间方法,有一个参数为委托类型
            public static void Calculat(int x, int y,myFirstDele myfirstDele) 
            {
                myfirstDele(x,y);
            }
                
        }

         8.面向对象的三大特性: 封装、继承、多态

         9.简要谈谈多态?

            定义:相同類型的對象調用相同的方法卻表現出不同的行為(不同的子類對象賦值給基類對象,該對象調用各自重寫基類的方法,當然會產生不同的行為)

            类别:编译时的多态(函数的重载) 运行时的多态(重写基类方法)

            实际上,多态的应用和继承紧密相关,当不确定具体返回类型(有多个类型)时,只需要返回基类,再将子类对象赋给基类对象,此时,可表达该子类对象

           抽象方法、虚方法可通过子类重写父类方法来实现多态

       //抽象方法實現多態 (抽象方法必须写在抽象类中)
       public abstract class Animal
        {
           //抽象方法沒有方法體
           public abstract void Skil();
        
        }
    
        public class Cat : Animal
        {
            public override void Skil()
            {
                Console.WriteLine("(重写基類方法)我是貓,會抓老鼠");
            }
            public void Test() 
            {
                Console.WriteLine("我是子類貓中特有的方法");
            }
        }
        //小狗类
        public class Dog : Animal 
        {
            public override void Skil()
            {
                Console.WriteLine("<重写基類方法>我是狗,我会看家护院");
            }
        }
        //麻雀类,除了基类中的技能,还拥有自己独特的飞能力
        public class Sparrow:Animal,Interface1
        {
            public override void Skil()
            {
                Console.WriteLine("<重写基類方法>我是麻雀,我非常靈活");
            }
            public void Fly() 
            {
                Console.WriteLine("<接口中方法>麻雀,我能衝上雲霄");
            }
        }
    
        ////虛方法實現多態
        //public class Animal
        //{
        //    //虛方法有方法體
        //    public virtual void Skil() { }
        //}

           接口亦如此,只是将继承了接口的类对象赋值给接口类,而接口中方法的实现仍然在继承接口的类的方法中

            static void Main(string[] args)
            {        
                Poly p = new Poly();
                //将子類對象赋值给父类
                Animal animal = new Cat();
                animal.Skil();
                //将继承了接口的类对象赋值给接口类
                Interface1 interface1 = new Sparrow();
                interface1.Fly();
                Console.ReadKey();
            } 

        overrite 和 new 的区别

        class Program
        {
            static void Main(string[] args)
            {
                var b = new bird();    //始终表达子类对象
                b.M1();
    
                animal animal = new bird();   //表达父类对象
                animal.M1();
                ((bird)animal).M1();    //表达子类对象,new 的访问类型必须是 Public,否则表达的仍是父类对象
                Console.ReadLine();
            }
        }
    
        public class animal 
        {
            public virtual void M1()
            {
               Console.WriteLine("我是动物父类");
            }
        }
    
        public class bird:animal
        {
            public new void M1()
           {
               Console.WriteLine("我是鸟,我会飞");
           }
        }

    10.什么接口?有什么作用?

         接口是对一组方法的声明进行统一命名,不提供实现,默认访问修饰符为Public,接口的产生源于C#中不允许多重继承

         调用接口:隐式,  对应继承单一接口  public 返回类型 方法名( ) {  ...  }  

         如果某个类中继承了多个具有相同名称、参数的方法,则在实现该接口中的方法时,需用到显示(指明具体来自的接口),注意:实现方法时,默认类型为Private私有,故无须添加访问修饰符。  样式为: 返回类型 接口名.方法名( ){  ... }  

    11.写一个递归的阶乘

            public int Jchen(int n) 
            {
                if (n==1)
                {
                    return 1;
                }
                else
                {
                    return Jchen(n-1)*n;
                }
            }

    12.写一个简单的冒泡程序( 2 for + 1 foreach )

            public void SSort(int [] ints) 
            {
                for (int i = 1; i < ints.Length; i++)
                {
                    for (int j = 0; j < ints.Length-1; j++)
                    {
                        int temp;
                        if (ints[j]>ints[j+1])
                        {
                            temp = ints[j+1];
                            ints[j + 1] = ints[j];
                            ints[j] = temp;
                        }
                    }             
                }
                foreach (var item in ints)
                {
                    Console.WriteLine(item);
                }
            }

     13. 字符串中 string.Empty、null、"" 三者有何区别?

      ① string.Empty 其值为 ""  ,在堆中分配了长度为0的一空间 . 可调用Tostring() , 与 "" 仅存在语法上的优化区别 , 只是Empty无须经过从字符串池中捞取 "" ,赋值给变量的过程.

      ② null  栈中存储的地址的指向是不确定的,故在堆中不分配内存空间 . 故不可调用Tostring().

    注:对于List<T> 泛型集合,null值不可调用对象的任何属性、方法; New之后可调用.

      

  • 相关阅读:
    面试题:1000!结果中有多少个0
    进程和线程的理解
    面试题:栈内存的多线程
    android中activity和service是否在同一个进程中
    面试题:栈排序
    面试题:递归反转一个栈
    面试题:栈的push和pop序列是否一致
    验证码发送到手机上 购买服务器进行发送短信;阿里云/ 腾讯云
    (十一)腾讯云短信使用
    (十)微信小程序---上传图片chooseImage 与 上传到服务器
  • 原文地址:https://www.cnblogs.com/Sientuo/p/6370137.html
Copyright © 2020-2023  润新知