C#語言基礎-02

C#語言基礎-02

寫這兩篇文章的目的是爲了備忘、 C#語言在大學讀書時候學過、當時做過一些東西、但是由於從事的主要工作和C#無關便忘記了。 近來公司增加了Unity業務、 寫Unity主要是C# 和js 想來C# 的語法結構和Java很相似、於是採用了C#語言作爲公司遊戲項目的主要語言。

本系列主要分上中下三篇文章來記錄。 分別牽涉到C# 中的初級、中級、高級內容。

由於本月一直忙於公司的項目、 所以發文就耽擱了, 但是回想五月忙上過去了,還是整理整理髮一篇吧。

本文主要寫一些關於C#語言的中級知識, 如果沒有看過初級的,可以先看上一篇文章,在電腦上敲敲試試,跑一下看看。

1. C# 調試和錯誤處理

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _01_中斷模式下的調試 {
    class Program {
         void Test()
        {
            Console.WriteLine("Test method");
        }
        static void Main(string[] args)
        {
            int num1 = 34;
            int num2 = 67;
            Test();
            int sum = num1 + num2;
            string name = "samuelnotes";
            Console.Write(sum);
            Console.WriteLine(name);
            Console.ReadKey();
        }
    }
}

在左邊點擊 添加斷點、 運行,調試。 可以盯着具體的變量名稱看運行中的變量內容, 同時可以根據運行時步驟,進行一步一步地查看結果,從而找出程序的問題所在。

2.錯誤與異常處理

來個例子、 沒有不出問題的代碼、 所以錯誤與異常的拋出控制的顯得很重要。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _002_錯誤處理_異常處理_ {
    class Program {
        static void Main(string[] args) {
            try
            {
                int[] myArray = {1, 2, 3, 4};
                int myEle = myArray[4];
            }
            catch (NullReferenceException e)//在這裏我們雖然寫了異常捕捉的程序,但是我們捕捉的類型不對,所以當發生別的類型的異常的時候,依然會終止程序的運行
            {
                Console.WriteLine("發生了異常:IndexOutOfRangeException");
                Console.WriteLine("您訪問數組的時候,下標越界了");
            }
            catch//當我們不寫catch的參數的時候,那麼這個catch會捕捉出現的任何異常信息
            {
                Console.WriteLine("您訪問數組的時候,下標越界了");
            }
            finally
            {
                Console.WriteLine("這裏是finally裏面執行的代碼");
            }

            
            Console.WriteLine("test");
            Console.ReadKey();
        }
    }
}

再來個例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _003_異常處理_案例2 {
    class Program {
        static void Main(string[] args)
        {
            int num1 = 0, num2 = 0;
            Console.WriteLine("請輸入第一個數字");
            while (true)
            {
                try {
                    num1 = Convert.ToInt32(Console.ReadLine());//在try塊中,如果有一行代碼發生了異常,那麼try塊中剩餘的代碼就不會執行了
                    break;
                } catch {
                    Console.WriteLine("您輸入的不是一個整數,請重新輸入");
                }
                //break;//把break放在這裏的話,不管發佈發生異常都會執行,因爲try對異常進行了處理
            }
            Console.WriteLine("請輸入第二個數字");
            while (true)
            {
                try {
                    num2 = Convert.ToInt32(Console.ReadLine());//在try塊中,如果有一行代碼發生了異常,那麼try塊中剩餘的代碼就不會執行了
                    break;
                } catch {
                    Console.WriteLine("您輸入的不是一個整數,請重新輸入");
                }
                //break;//把break放在這裏的話,不管發佈發生異常都會執行,因爲try對異常進行了處理
            }
            int sum = num1 + num2;
            Console.WriteLine(sum);
            Console.ReadKey();

        }
    }
}

3. 面向對象編程-類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _005_面向對象編程_類 {
    class Program {
        static void Main(string[] args) {
            //1,如果要使用一個類的話 要先引入它所在的命名空間,因爲customer位於當前的命名空間下,所以不需要引入,我們可以直接使用Customer
            
            Customer customer1;//在這裏我們使用Customer模板,聲明瞭一個變量(對象)
            customer1 = new Customer();//對對象初始化 需要使用new加上類名
            customer1.name = "siki";//我們自己定義的類聲明的對象,需要先進行初始化,才能使用 
            Console.WriteLine(customer1.name);
            customer1.Show();//使用對象中的方法
            Console.ReadKey();
        }
    }
}
namespace _005_面向對象編程_類 {
    //在這裏我們定義了一個新的類叫做Customer,也可以說定義了一個新的類型叫做Customer
    class Customer
    {
        //數據成員:裏面包含了4個字段
        public string name;
        public string address;
        public int age;
        public string buyTime;
        //函數成員:定義了一個方法
        public void Show()
        {
            Console.WriteLine("名字:"+name);
            Console.WriteLine("年齡:"+age);
            Console.WriteLine("地址:"+address);
            Console.WriteLine("購買時間:"+buyTime);
        }
    }

4. 類的定義和聲明

再來個例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _006_類的定義和聲明 {
    class Program {
        static void Main(string[] args) {
            //Vehicle car1 = new Vehicle();
            //car1.speed = 100;
            //car1.Run();
            //car1.Stop();
            //Console.WriteLine(car1.speed);
            //Vector3 v1 = new Vector3();
            //v1.x = 1;
            //v1.y = 1;
            ////v1.z = 1;
            //v1.SetX(1);
            //v1.SetY(1);
            //v1.SetZ(1);
            Vector3 v1 = new Vector3(1,1,1);
            //Console.WriteLine(v1.Length());

            //使用屬性
            //v1.MyIntProperty = 600;//對屬性設置值
            //int temp = v1.MyIntProperty;//對屬性取值
            //Console.WriteLine(temp);
            //v1.X = 100;
            //Console.WriteLine(v1.X);
            v1.Name = "siki";
            Console.WriteLine(v1.Name);
            Console.ReadKey();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _006_類的定義和聲明 {
    public class Vector3//設置爲public 這樣才別 的項目中纔可以訪問
    {
        //我們定義了一個構造函數,那麼編譯器不會爲我們提供構造函數了
        public Vector3()
        {
            Console.WriteLine("Vector3的構造函數被調用了");
        }

        public Vector3(float x, float y, float z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
            length = Length();
        }
        //編程規範上 習慣把所有的字段 設置爲private ,只可以在類內部訪問,不可以通過對象訪問
        private float x, y, z, length;
        private int age;
        //private string name;

        //public String Name
        //{
        //    get { return name; }
        //    set { name = value; }
        //}
        public string Name { get; set; }//編譯器會自動給我們提供一個字段,來存儲name


        public int Age
        {
            set
            {
                //通過set方法 在設置值之前做一些校驗的工作  屬性的更多好處,需要在寫代碼過程中體會
                if (value >= 0)
                {
                    age = value;
                }
            }
        }

        public float X// 也可以叫做get set方法
        {
            get { return x; }
            set { x = value; }//如果在get 或者 set前面加上 private,表示這個塊只能在類內部調用
        }
        //爲字段提供set方法,來設置字段的值
        public void SetX(float x)
        {
            //如果我們直接在方法內部訪問同名的變量的時候,優先訪問最近 (形參)
            //我們可以通過this.表示訪問的是類的字段或者方法
            this.x = x;
        }

        public void SetY(float y)
        {
            this.y = y;
        }

        public void SetZ(float z)
        {
            this.z = z;
        }

        public float Length() {
            return (float)Math.Sqrt(x * x + y * y + z * z);
        }
        //定義屬性
        public int MyIntProperty {
            set {
                Console.WriteLine("屬性中set塊被調用");
                Console.WriteLine("在set塊中訪問value的值是:"+value);
            }
            //如果沒有get塊,就不能通過屬性取值了
            get {
                Console.WriteLine("屬性中的get塊被調用 ");
                return 100;
            }
        }
    }
}

    class Vehicle
    {
        public float speed;
        public float maxSpeed;
        public float weight;

        public void Run()
        {
            Console.WriteLine("這個車正在以"+speed+"m/s的速度前行");
        }

        public void Stop()
        {
            speed = 0;
            Console.WriteLine("車輛停止");
        }
    }

5. 值類型和引用類型

程序運行時候內存的佔用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _008_值類型和引用類型___程序運行時候內存的佔用 {
    class Program {
        static void Main(string[] args)
        {
            //Test1();
            //Test2();
           // Test3();
            //Test4();
            Test5 ();
            
            Console.ReadKey();
        }

        static void Test1()
        {
            int i = 34;
            int j = 34;
            int temp = 334;
            char c = 'a';
            bool b = true;
        }

        static void Test2()
        {
            int i = 34;
            int j = 234;
            string name = "siki";

        }

        static void Test3()
        {
            string name = "siki";
            string name2 = "taikr";
            name = name2;
            name = "google";
            Console.WriteLine(name+":"+name2);
        }

        static void Test4()
        {
            Vector3 v = new Vector3();
            v.x = 100;
            v.y = 100;
            v.z = 100;
            Vector3 v2 = new Vector3();
            v2.x = 200;
            v2.y = 200;
            v2.z = 200;
            v2 = v;
            v2.x = 300;
            Console.WriteLine(v.x);
        }

        static void Test5()
        {
            Vector3[] vArray = new Vector3[]{ new Vector3(), new Vector3(), new Vector3() };//如果數組是一個值類型的數組,那麼數組中直接存儲值,如果是一個引用類型的數組(數組中存儲的是引用類型),那麼數組中存儲的是引用(內存地址)
            Vector3 v1 = vArray[0];
            vArray[0].x = 100;
            v1.x = 200;
            Console.WriteLine(vArray[0].x);
        }
    }
}

/// 空間位置類
class Vector3
    {
        public float x, y, z;
    }

6. 面向對象編程繼承

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _009_面向對象編程_繼承 {
    class Program {
        static void Main(string[] args) {
            //Boss boss = new Boss();
            ////boss.AI();//繼承:父類裏面所有的數據成員和函數成員都會繼承到子類裏面
            //boss.Attack();

            //Enemy enemy;
            //enemy = new Boss();//父類聲明的對象,可以使用子類去構造  子類聲明的對象不可以使用父類構造
            ////enemy雖然使用父類進行了聲明,但是使用了子類構造,所以本質上是一個子類類型的,我們可以強制類型轉換轉換成子類類型
            //Boss boss = (Boss)enemy;
            //boss.Attack();

            //Enemy enemy = new Enemy();
            //Boss boss =(Boss) enemy;//一個對象是什麼類型的  主要看它是通過什麼構造的  這裏enemy使用了父類的構造函數,所以只有父類中的字段和方法, 不能被強制轉換成子類

            //Boss boss = new Boss();
            ////boss.Attack();
            //boss.AI();

            //Enemy enemy = new Enemy();
            //enemy.AI();

            //Enemy boss = new Boss();
            //boss.Move();//隱藏方法: 如果使用子類聲明的對象,調用隱藏方法會調用子類的,如果使用父類聲明對象,那麼就會調用父類中的隱藏方法

            //Crow crow = new Crow();
            //crow.Fly();

            //Bird bird = new Crow();//我們可以通過抽象類去聲明對象 但是不可以去構造
            //bird.Fly();


            Console.ReadKey();
        }
    }
}
   abstract class Bird//一個抽象類 就是一個不完整的模板
    {
        private float speed;

        public void Eat()
        {
            
        }

        public abstract void Fly();
    }
    
     class Boss : Enemy{
        //public override void Move()//重寫 : 原來的方法不存在了
        //{
        //    Console.WriteLine("這裏是Boss的移動方法");
        //}
        public new void Move()//當子類裏面有一個簽名和父類相同的方法的時候,就會把父類中的方法隱藏
        {//隱藏: 只是把父類中的方法隱藏了,看不到了,實際這個方法還存在
            Console.WriteLine("這裏是Boss的移動方法");
        }
        public void Attack()
        {

            //AI();
            //Move();
            ////hp = 100;
            //HP = 100;//父類裏面公有是數據和函數成員纔可以在子類裏面訪問
            Move();
            Console.WriteLine("Boss正在進行攻擊");
        }
    }
     class Crow:Bird {//我們繼承了一個抽象類的時候,必須去實現抽象方法
        public override void Fly()
        {
            Console.WriteLine("烏鴉在飛行");
        }
    }
    
    class Enemy
    {
        private float hp;
        private float speed;

        public float HP
        {
            get { return hp; }
            set { hp = value; }
        }

        public float Speed
        {
            get { return speed; }
            set { speed = value; }
        }

        public void AI()
        {
            //Move();
            Console.WriteLine("這裏是Enemy1的公有AI方法");
        }

        //public virtual void Move()
        //{
        //    Console.WriteLine("這裏是Enemy1的公有Move方法");
        //}
        public void Move()
        {
            Console.WriteLine("這裏是Enemy1的公有Move方法");
        }

        public void A()
        {
            Console.WriteLine("Enemy A");
        }

    }
     class Type1Enemy:Enemy {
    }
    
       class Type2Enemy:Enemy {
    }

7. 密封類和密封方法

class BaseCLass {
        public virtual void Move()
        {
            
        }
    }
    
       class DerivedClass:BaseCLass {//sealed密封類無法被繼承
        public sealed override void Move()//我們可以把重寫的方法聲明爲密封方法,表示該方法不能 被重寫 
        {
            base.Move();
        }
    }

8. 派生類的構造函數

 class BaseClass
    {
        private int x;
        protected int z;
        public BaseClass()
        {
            Console.WriteLine("base class 無參構造函數");
        }

        public BaseClass(int x)
        {
            this.x = x;
            Console.WriteLine("x賦值完成");
        }
    }
     class ClassXyz
    {
        public static int z;//靜態字段

        public static void TestMethod()
        {
            Console.WriteLine("這是靜態方法");
        }
        private int x;
        private int y;
    }
    
    class DerivedClass:BaseClass
    {
        private int y;
        public DerivedClass()//調用父類中無參的構造函數 當我們沒有在子類的構造函數中顯示聲明調用父類的構造函數,默認會調用父類中的無參構造函數
        {
            Console.WriteLine("這個是DerivedClass 無參的構造函數");   
        }

        public DerivedClass(int x, int y):base(x)
        {
            this.y = y;
            base.z = 100;
            Console.WriteLine("y賦值完成");
        }
    }
    
     class Program {
        static void Main(string[] args) {//public private
            //DerivedClass o1 = new DerivedClass();
            //DerivedClass o2= new DerivedClass(1,2);
            //BaseClass o1 = new BaseClass();

            ClassXyz.z = 100;
            Console.WriteLine(ClassXyz.z);
            ClassXyz.TestMethod();

            Console.ReadKey();
        }
    }
    
    

9. 定義和實現接口

 interface IA
    {
        void Method1();
    }
    
      interface IB:IA
    {
        void Method2();
    }
    
       interface IFly
    {
        void Fly();
        void MethodA();
    }
    
 class Bird :IFly,IB{
        public void Fly()
        {
            
        }

        public void MethodA()
        {
            
        }

        public void Method1()
        {
            
        }

        public void Method2()
        {
            
        }
    }

10. 列表List的創建和使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _010_列表List的創建和使用 {
    class Program {
        static void Main(string[] args) {
            //List<int> scoreList = new List<int>();//創建了一個空的列表 通過類型後面的<>來表示這個列表存儲的數據的類型
            var scoreList = new List<int>();
            //var scoreList = new List<int>(){1,2,3};//創建了一個列表,裏面的初始值有三個分別爲 1 2 3
            //Console.WriteLine("capacity:"+scoreList.Capacity+" count:"+scoreList.Count);
            //scoreList.Add(12);//向列表中插入數據
            //Console.WriteLine("capacity:" + scoreList.Capacity + " count:" + scoreList.Count);
            //scoreList.Add(45);
            //Console.WriteLine("capacity:" + scoreList.Capacity + " count:" + scoreList.Count);
            //Console.WriteLine(scoreList[0]);//根據索引訪問數據

            for (int i = 0; i < 20; i++)
            {
                Console.WriteLine("capacity:" + scoreList.Capacity + " count:" + scoreList.Count);
                scoreList.Add( 10 );
            }

            //Console.WriteLine(scoreList[2]);//索引不存在的時候,會出現異常
            Console.ReadKey();
        }
    }
}

 class Program {
        static void Main(string[] args)
        {
            var scoreList = new List<int>();
            scoreList.Add(34);
            scoreList.Add(334);
            scoreList.Add(3344);
            scoreList.Add(344);
            scoreList.Add(32344);
            scoreList.Add(134);
            scoreList.Add(334);
            //for (int i = 0; i < scoreList.Count; i++)
            //{
            //    Console.Write(scoreList[i]+" ");
            //}
            foreach (var temp in scoreList)
            {
                Console.Write(temp+" ");
            }
            Console.ReadKey();
        }
    }

11. 操作列表的屬性和方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _011_操作列表的屬性和方法 {
    class Program {
        static void Main(string[] args) {
            var scoreList = new List<int>();
            scoreList.Add(100);
            scoreList.Add(200);
            scoreList.Add(300);
            scoreList.Add(100);
            foreach (var temp in scoreList)
            {
                Console.Write(temp+" ");
            }
            Console.WriteLine();
            //scoreList.Insert(3, -1);//向指定索引位置插入元素
            //foreach (var temp in scoreList) {
            //    Console.Write(temp + " ");
            //}
            //Console.WriteLine();
            //scoreList.RemoveAt(0);
            //foreach (var temp in scoreList) {
            //    Console.Write(temp + " ");
            //}
            //Console.WriteLine();
            //int index  =scoreList.IndexOf(400);
            //Console.WriteLine(index);
            //Console.WriteLine( scoreList.IndexOf(100) );
            //Console.WriteLine( scoreList.LastIndexOf(100) );
            scoreList.Sort();
            foreach (var temp in scoreList) {
                Console.Write(temp + " ");
            }
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

12. 泛型- 泛型類 - 泛型方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _012_泛型_泛型類 {
    class ClassA<T,A> {//T代表一個數據類型,當使用classA進行構造的時候,需要制定T的類型
        private T a;
        private T b;
        private A c;

        public ClassA(T a, T b )
        {
            this.a = a;
            this.b = b;
        }

        public string  GetSum()
        {
            
            return a +""+ b;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _012_泛型_泛型類 {
    class Program {
        static void Main(string[] args) {
            //var o1 = new ClassA<int>(12,34);//當我們利用泛型類構造的時候,需要制定泛型的類型
            //string s = o1.GetSum();
            //Console.WriteLine(s);
            var o2 = new ClassA<string,int>("wwww.","samuelnotes.cn");
            Console.WriteLine(o2.GetSum());
            Console.ReadKey();
        }
    }
}

13. 使用泛型和索引器來實現一個我們自己的集合類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _013_泛型方法 {
    class Program {
        public static string GetSum<T,T2,T3,T4>(T a, T b)
        {
            return a + "" + b;
        } 
        static void Main(string[] args) {
            Console.WriteLine(GetSum<int,int,int,int>(12,34));
            Console.WriteLine(GetSum<double,double,double,double>(12.3,34.5));
            Console.WriteLine(GetSum<string,string,string,string>("23r,","wer3l2kj"));
            Console.ReadKey();
        }
    }
}

14. 總結

還是那句話、多思考、上手敲代碼、 調試調試、多試試。 如果有問題可以評論區留言共同學習進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章