C# - 高级编程


C# - 高级编程

结构Struct

struct 结构体

实例

using System;

namespace HelloWord
{
    struct Game
    {
        public string name;
        public string developer;
        public DateTime releaseDate;

        public Game(string name, string developer, DateTime releaseDate)
        {
            this.name = name;
            this.developer = developer;
            this.releaseDate = releaseDate;
        }

        public void GetInfo()
        {
            Console.WriteLine("游戏名称", name);
            Console.WriteLine("开发", developer);
            Console.WriteLine("上架日期", releaseDate);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            Game game;
            game.name = "pokemon";
            game.developer = "LI";
            game.releaseDate = DateTime.Today;

            game.GetInfo();

            Console.Read();
        }
    }
}

结构体的使用场景

  • 电脑的内存分为堆内存栈内存
  • 堆内存空间远大于栈内存,但是栈内存执行效率却高于堆内存
  • 引用类型保存在堆内存中,而值类型则保存在栈内存。
  • class对象是引用类型,保存在堆内存中,执行效率比较低。
  • struct是值类型,保存在栈内存中,运行效率高。

class的使用场景

  • 抽象的概念、或者需要多个层级来表现对象关系。
  • 适用于结构复杂的数据。

结构体的特点

  • 可带有方法、字段、索引、属性、运算符方法和事件。
  • 结构不能定义无参的默认构造方法。
  • 结构可实现接口,但它不能继承,也不能被继承。
  • 实例化可以使用new(),但也可以不用new()

枚举Enum

实例

using System;

namespace HelloWord
{
    class Program
    {
        enum Weekday
        {
            MONDAY = 1,
            TUESDAY,
            WEDNESDAY,
            THURSDAY,
            FRIDAY = 5,
            SATURDAY,
            SUNDAY
        }

        static void Main(string[] args)
        {
            Weekday firday = Weekday.FRIDAY;

            Console.WriteLine(firday);
            Console.WriteLine((int)firday);

            var firday2 = (Weekday)4;
            Console.WriteLine(firday2);

            Weekday day = Weekday.MONDAY;

            switch(day)
            {
                case Weekday.MONDAY:
                case Weekday.TUESDAY:
                case Weekday.WEDNESDAY:
                case Weekday.THURSDAY:
                case Weekday.FRIDAY:
                    Console.WriteLine("今天要上班");
                    break;
                case Weekday.SUNDAY:
                case Weekday.SATURDAY:
                    Console.WriteLine("家里蹲");
                    break;
            }

            Console.Read();
        }
    }
}

泛型入门

泛型

实例

using System;

namespace HelloWord
{
    class Program
    {
        static void Main(string[] args)
        {
            //var numberlist = new List();
            var numberlist = new GenericList<int>();
            numberlist.Add(1);
            numberlist.Add(2);

            //var productList = new ProductList();
            var productList = new GenericList<Product>();
            productList.Add(new Product()
            {
                Id = 1, 
                Price = 100
            });
            productList.Add(new Product()
            {
                Id = 2,
                Price = 200
            });
            
            var dic = new System.Collections.Generic.Dictionary<string, Product>();
            dic.Add("123", new Product());
            dic.Add("234", new Product());
            dic.Add("345", new Product());

            Product product;
            dic.TryGetValue("123", out product);

            Nullable<int> number = new Nullable<int>();
            Console.WriteLine(number.HasValue);

            var number2 = new Nullable<int>(5);
            number2.GetValueOrDefault();

            Console.Read();
        }
    }
}

泛型进阶

Book.cs

namespace HelloWord
{
    public class Book : Product
    {
        public string ISBN { get; set; }
    }
}

DiscountCalculator.cs

using System;

namespace HelloWord
{
    public class DiscountCalculator<T> where T : Product
    {

    }

    // where T : IComparable
    // where T : Product
    // where T : struct
    // where T : new()
    public class Utility<T> where T : IComparable, new()
    {
        public int FindMax(int a, int b)
        {
            return a > b ? a : b;
        }

        public T FindMax(T a, T b)
        {
            return a.CompareTo(b) > 0 ? a : b;
        }

        public void DoSomething()
        {
            var obj = new T();
        }
    }
}

List.cs

using System;

namespace HelloWord
{
    public class List
    {
        public void Add(int number)
        {
            throw new NotImplementedException();
        }

        public int this[int index]
        {
            get { throw new NotImplementedException(); }
        }
    }
}

Nullable.cs

namespace HelloWord
{
    public class Nullable<T> where T : struct
    {
        public Nullable() { }

        private object _value;

        public Nullable(T value)
        {
            _value = value;
        }

        public bool HasValue
        {
            get
            {
                return _value != null;
            }
        }

        public T GetValueOrDefault()
        {
            if (HasValue)
            {
                return (T)_value;
            }
            return default(T);
        }
    }
}

Product.cs

namespace HelloWord
{
    public class Product
    {
        public int Id { get; set; }
        public decimal Price { get; set; }
    }
}

ProductList.cs

using System;

namespace HelloWord
{
    public class ProductList
    {
        public void Add(Product order)
        {
            throw new NotImplementedException();
        }

        public Product this[int index]
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class ObjectList
    {
        public void Add(object o)
        {
            throw new NotImplementedException();
        }

        public object this[int index]
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class GenericList<T>
    {
        public void Add(T o)
        {
            throw new NotImplementedException();
        }

        public T this[int index]
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class Dictionary<TKey, TValue>
    {
        public void Add(TKey key, TValue value)
        {
            throw new NotImplementedException();
        }

        public TValue get(TKey key)
        {
            throw new NotImplementedException(); 
        }
    }
}

Program.cs

using System;

namespace HelloWord
{
    class Program
    {
        static void Main(string[] args)
        {
            //var numberlist = new List();
            var numberlist = new GenericList<int>();
            numberlist.Add(1);
            numberlist.Add(2);

            //var productList = new ProductList();
            var productList = new GenericList<Product>();
            productList.Add(new Product()
            {
                Id = 1, 
                Price = 100
            });
            productList.Add(new Product()
            {
                Id = 2,
                Price = 200
            });
            
            var dic = new System.Collections.Generic.Dictionary<string, Product>();
            dic.Add("123", new Product());
            dic.Add("234", new Product());
            dic.Add("345", new Product());

            Product product;
            dic.TryGetValue("123", out product);

            Nullable<int> number = new Nullable<int>();
            Console.WriteLine(number.HasValue);

            var number2 = new Nullable<int>(5);
            number2.GetValueOrDefault();

            Console.Read();
        }
    }
}

空处理Nullable

值类型 vs 引用类型

  • C#中DateTime却是值类型数据,需要特殊处理才能赋值为null。

实例

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

namespace _36Nullables
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Nullable<DateTime> date = null;
            //这两是一样的
            DateTime? date2 = new DateTime(2099,1,21);
            DateTime? date3 = date.GetValueOrDefault();
            DateTime? date4= date3;

            if (date4.HasValue)
            {
                Console.WriteLine(date3.GetValueOrDefault());
            }
            else {
                Console.WriteLine(DateTime.Today);
            }
            //这两也是一样的,??合并操作符
            var result = date4 ?? DateTime.Today;
            Console.WriteLine(result);  

/*            Console.WriteLine(date.GetValueOrDefault());
            Console.WriteLine(date.HasValue);
*//*            Console.WriteLine(date.Value);*/

            Console.Read();
        }
    }
}

拓展方法Extesion

  • 允许我们向一个已经存在的class中添加拓展代码。
  • 不需要修改原class的代码。
  • 不需要继承原class。

实例

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace HelloWord
{
    class Program
    {
        static void Main(string[] args)
        {
            string hello = "Hello World";
            Console.WriteLine(hello.ShortTerm(2)); // He

            IEnumerable list = new List<int>();
            //list.

            Console.Read();
        }
    }

    public static class StringExtension
    {
        public static string ShortTerm(this string str, int num)
        {
            return str.Substring(0, num);
        }
    }

    //class RichString: String
    //{

    //}

}

动态类型dynamic

C#属于强语言,同时略偏静态类型

  • 强类型语言,因为它不支持类型的自动转化。
  • 主要是静态语言,但是因为存在dynamic这个关键词,所以它也具有动态类型的特点。

实例

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

namespace _38dynamic
{
    public class Excel
    {
        public string Table { get; set; }
        public void ShowTable()
        {
            Console.WriteLine("打印excel表格");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //object obj = new Excel();
            //var obj = new Excel();
            dynamic obj = new Excel();
            obj.GetHashCode();
            obj.ShowTable();

            //var methodInfo = obj.GetType().GetMethod("ShowTable");
            //methodInfo.Invoke(obj, null);

            obj = "hello world";

            Console.Read();
        }
    }
}

反射与元数据(.NET特性)

反射 Reflection

  • 实例化对象,但不使用new ,不知道目标对象类型。

元数据 Metadata

元数据 = 关于数据的数据

  • 数据库的数据、文件上的数据。
  • 而程序本身,其实也同样是数据。
  • 在运行的过程中查看或者使用元数据的过程就叫做反射

反射的过程

  • 元数据报存在程序集(Assembly)中。

实例

List.cs

using System;

namespace HelloWord
{
    public class List
    {
        public void Add()
        {
            Console.WriteLine("ddddddd");
        }
    }
}

Program.cs

using System;
using System.Reflection;

namespace HelloWord
{
    class Program
    {
        static void Main(string[] args)
        {
            // 定位类                      命名空间.类名,   项目名称
            const string classLocation = "HelloWord.List, HelloWord";

            // 获取 List 类型对象
            Type objectType = Type.GetType(classLocation);

            // 通过类型实例化
            object obj = Activator.CreateInstance(objectType);

            // 调用“Add”方法
            MethodInfo add = objectType.GetMethod("Add");
            add.Invoke(obj, null);

            Console.Read();
        }
    }
}

反射的特点

  • 不使用new关键词,我们也同样可以也可以实例化对象。
  • 不用new关键词,就意味着我们可以对系统做出进一步的解耦。

非反射 与 反射

非反射

反射

反射与依赖注入

为什么需要反射

  • 某些业务逻辑并不是我们在写程序的时候就能确定的。
  • 静态环境中预测用户的行为非常困难。

反射的应用场景

  • 单元测试、反转控制、依赖注入、泛型。
  • 反射机制是.net框架中处于一个比较底层的位置。
  • 一般不会直接接触。

反射实战

新建项目和在“解决方案”中新建项目(类库)

给Computer.SDK类库添加新建项 —— 接口(IUSB.cs)

using System;
namespace Computer.SDK
{
    public interface IUSB
    {
        void GetInfo();
        void Read();
        void Write();   
    }
}

创建FlashDisk类库

导入Computer.SDK类库 —— 给FlashDisk类库添加Computer.SDK依赖项

在FlashDisk类库下创建FlashDisk类

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

namespace FlashDisk
{
    public class FlashDisk : Computer.SDK.IUSB
    {
        public void GetInfo()
        {
            Console.WriteLine("32g");
        }

        public void Read()
        {
            Console.WriteLine("读取");
        }

        public void Write()
        {
            Console.WriteLine("写入");
        }
    }
}

创建SSD类库 _ 导入Computer.SDK类库 —— 给SSD类库添加Computer.SDK依赖项

在SSD类库下创建SSD类

using System;

namespace SSD
{
    public class SSD : Computer.SDK.IUSB
    {
        public void GetInfo()
        {
            Console.WriteLine("1t");
        }

        public void Read()
        {
            Console.WriteLine("读取1t");
        }

        public void Write()
        {
            Console.WriteLine("写入1t");
        }
    }
}

在项目文件夹.binDebug中创建USB接口(文件夹)

生成SSD.DLL

将.SSDbinDebugnet6.0路径下的SSD.DLL复制到USB接口(文件夹)

将.FlashDiskbinDebugnet6.0路径下的FlashDisk.DLL复制到USB接口(文件夹)

Program.cs —— 新建依赖项(Computer.SDK)

using System;
using System.IO;
using System.Runtime.Loader;
using System.Collections;
using System.Collections.Generic;
using Computer.SDK;

namespace Computer
{
    class Program
    {
        static void Main(string[] args)
        {

            // 程序路径
            var USBInterface = Path.Combine(Environment.CurrentDirectory, "USB");
            Console.WriteLine(USBInterface);

            // 文件读写操作
            var dllFiles = Directory.GetFiles(USBInterface);

            // USB 设备列表
            var devicesList = new List<IUSB>();

            foreach (var dll in dllFiles)
            {
                var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(dll);
                var types = assembly.GetTypes();
                foreach (var type in types)
                {
                    var interfaceList = type.GetInterfaces();
                    foreach (var i in interfaceList)
                    {
                        if (i.Name == "IUSB")
                        {
                            IUSB device = (IUSB)Activator.CreateInstance(type);
                            devicesList.Add(device);
                        }
                    }
                }
            }

            foreach (var devices in devicesList)
            {
                devices.GetInfo();
                devices.Read();
                devices.Wirte();
            }

            Console.Read();
        }
    }
}

调试

异常处理exceptionhalding

using System;
using System.IO;

namespace HelloWord
{
    public class Calculator
    {
        public int Divde(int numerator, int denomenator)
        {
            return numerator / denomenator;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            StreamReader streamReader = null;

            try
            {
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                string fullName = Path.Combine(desktopPath, "123.txt");
                streamReader = new StreamReader(fullName);
                var connect = streamReader.ReadToEnd();

                // 操作文件

                // 人为抛出异常
                throw new Exception("Oops");

                // 关闭文件,回收垃圾
                streamReader.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine("系统异常");
            }
            finally
            {
                if (streamReader != null)
                {
                    streamReader.Dispose();
                    Console.WriteLine("文件回收");
                }
            }

            Console.Read();
        }
    }
}

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - C# - 高级编程


三二一的一的二