• .Net深入体验与实践第一章


    什么是委托?委托和事件是什么关系?

    我的理解是委托朋友,事件是一个事情比如,中午12点要吃饭了,咱家搞忘了!还在继续嗨皮,我的朋友会叫我与他一起吃饭。

    什么事反射?

    可以获取.Net中的每个类型(类,结构,委托,结构,和枚举)包含所有,有了反射,可对每一个类型了如指掌

    C#中的多个类基础?如何实现多重继承,如何派生?

    C#中是没有类的多重继承这个概念.c#中类继承值能是一个,即子类派生于父类。

    C#要使用多重继承必须要通过接口Interface来完成。

    C#如果要实现派生,一种是隐藏基类,一种是使用abstract,还有一种是virtual。

    什么是密封类?

    就是不让这个类被继承

    using 关键字的几种用途?

    #waring和#error分别的用途是什么?

    Asp.Net web应用程序和Asp.NET网站的区别是什么?

    什么事委托?

    咱家:在c/c++中使用过函数指针和类成员函数指针,所谓的函数指针和类成员函数指针,都是声明一种与函数指针或者类成员函数参数相同将其的名称挖掉,在用这个声明去接受这个这个函数,或者类成员函数,这个这个声明就存储了他的地址,就可以通过这个声明从而来操作这个函数;

    为了方便识别咱家用c举了一个例子:

    #include<stdio.h>
    #include<stdlib.h>


    int cheng(int a, int b)
    {
    return a*b;
    }
    int chu(int a, int b)
    {
    return a / b;
    }
    void main()
    {
    int(*p)(int a, int b) = cheng;//存储函数指针的地址
    printf("%d", p(15, 3));

    system("pause");
    }

    我使用的编译工具是code::blocks,是纯c的编译环境

    或许有些同志想说明明c#你玩什么C?

    一、我只想说在我的理解中c#的委托像操作变量一样来操作函数,所以与c的相识,下面我们进入“正题”定义一个委托

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

    namespace 委托
    {
    //声明委托类型
    public delegate void SayDelegate(string name);                  //定义一个函数类型的委托
    class ClassPeople
    {
    public void SayA(string name)
    {
    Console.WriteLine("你好,{0}",name);
    }
    public void SayB(string name)
    {
    Console.WriteLine("Hello,{0}",name);
    }

                                  //注意此方法,他接受一个SayDelegate类型的方法做为参数
    public void DoWork(string name,SayDelegate MakeSay)
    {
    MakeSay(name);                                                                           //通过这个变量来操作函数
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    ClassPeople p = new ClassPeople();
    p.DoWork("小李子", p.A);
    p.DoWork("XiaoLiZhi", p.B);

    Console.ReadLine();

    }
    }
    }

    多播委托可以将多个相同的函数类型的赋值给一个委托,或者将多个方法帮定到一个委托,这就是多播委托

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

    namespace 委托
    {
    //声明委托类型
    public delegate void SayDelegate(string name);
    class ClassPeople
    {
    public void A(string name)
    {
    Console.WriteLine("你好,{0}",name);
    }
    public void B(string name)
    {
    Console.WriteLine("Hello,{0}",name);
    }

    //注意此方法,他接受一个SayDelegate类型的方法做为参数
    public void DoWork(string name,SayDelegate MakeSay)
    {
    MakeSay(name);
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    ClassPeople p = new ClassPeople();
    p.DoWork("小李子", p.A);
    p.DoWork("XiaoLiZhi", p.B);
    //多播委托可以将多个相同类型的赋值给一个委托,或者将多个方法帮定到一个委托,这就是多播委托
    SayDelegate delegate1 = p.A;     
    delegate1 += p.B;                                                                         //将多个相同类型赋值到一个委托中
    p.DoWork("XiaoLiZhi",delegate1);
    Console.ReadLine();
    }
    }
    }

     

    二、委托和事件

    下面我将使用烧水的事件和委托来为同志们演示哈,书上的我高级太高端了,也太复杂了,我也看个半懂,我使用’循环来判断是否触发这个事件‘循环要比快定时器简单些,如果是定时器我又要看哈书懒得看。应该要详细演示,所以使用了多个事件,一个警告的,一个提示开了的。

    event <委托类型> 事件名

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

    namespace 事件
    {
    class Program
    {
    //烧水类
    class Heater
    {
    private int temperature; //传递温度
    public delegate void BoilHeater(int arg); //声明委托
    public event BoilHeater BoilEvent; //声明事件

    //烧水的
    public void BoliWater()
    {
    for(int i=0;i<=100;i++)
    {
    temperature = i;
    if (temperature >= 95)
    {
    if (BoilEvent != null) //如果没有对象注册
    {
    BoilEvent(temperature); //触发事件调用委托
    }
    }
    }

    }
    }

    //超过95度后报警
    public class Alarm
    {
    public static void MakeAlert(int arg)
    {
    Console.WriteLine("Alarm:搞快点,还不得忙,水{0}度了", arg);
    }
    }
    //显示的
    public class Show
    {
    public void ShowMsg(int arg) //使用了静态的
    {
    Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", arg);
    }
    }

    static void Main(string[] args)
    {
    Heater headter = new Heater();
    headter.BoilEvent += Alarm.MakeAlert; //将烧水的加入事件
    headter.BoilEvent += (new Show()).ShowMsg; //应为没有使用static所以需要new对象,不这儿new可以在外面new了一样的,我比较懒你懂的
    //事件添加好了,启动烧水的了
    headter.BoliWater(); //启动烧水的
    Console.Read();
    }
    }
    }

    三 、反射

     下面的话是咱家抄的书上的

    反射(Reflection)是,NET中的重要机制,通过反射,可以对运行时获的.NET中的每一个类型(包括类,结构,委托,接口,和枚举等)的成员,包括方法,属性,事件,已经构造函数等,还可以获得每个成员的名称,限定符和参数等,有了反射,即可对每个类型了了如指掌,只要获得了构造函数的信息,即可直接创建对象,即使对这个对象的类型在编译时还不知道,咱家抄袭的话是不是感觉很牛逼,好像网上同志的解释:是简单的说反射是为了动态地运行时加载,而静态代码是在编译时就确定好了。也就是说当你的程序需要在运行时再做一些晚绑定,动态加载或检查对象等操作时,你就需要用到反射啦,不过我感觉w某某好像没说过也,我估计怕是遇到了个假的w某某,开玩笑的,估计是他老人家忘了。

    下面进入正题Assembly.Load 

    Assembly.LoadFile 
    Assembly.LoadFrom 
    Type对象的Assembly方法

    MemberInfo-成员 
    ConstructorInfo-结构 
    FieldInfo-字段 
    MethodInfo-方法 
    PropertyInfo-属性 
    EventInfo-事件

    第一个要生成类库,所以必须的使用”类库“创建程序生成 ”反射类库.dll“把dll引用到第二个程序中实现反射

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

    namespace 反射类库
    {

    class Person
    {
    public Person() //空的构造
    {

    }
    public Person(string name) //有参的构造
    {
    this.name = name;
    }
    private string name;
    public string Name //将字段可以传出或者设置
    {
    get { return name; }
    set { name = value; }
    }
    public void SayHello()
    {
    if (name == null)
    {
    Console.WriteLine("Hello World!");
    }
    else
    {
    Console.WriteLine("Hello {0}", name);
    }
    }

    }
    }

     实现反射

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

    namespace 反射
    {
    class Program
    {

    static void Main(string[] args)
    {
    //我们可以通过Assembly的信息来获取程序的类,实例等编程需要用到的信息
    Console.WriteLine("列出程序集中的所有类型");
    Assembly ass = Assembly.LoadFrom("反射类库.dll");
    //c#中通过Type类可以访问任意数据类型信息
    Type Person = null;
    Type[] mytypes = ass.GetTypes();
    foreach (Type item in mytypes)
    {
    Console.WriteLine(item.Name);
    if(item.Name=="Person") //如果名称与Person
    {
    Person = item; //将反”射类库中.dll“中的Person赋值当当前的Person
    }
    }

    Console.WriteLine("列出Person类中的所有方法");
    //MeberInfo获取成员属性信息,并对成员提供访问
    //GetMethods返回当前所有的public方法
    MemberInfo[] mif = Person.GetMethods();
    foreach (MemberInfo item in mif)
    {
    Console.WriteLine(item.Name); //打印Person中的所有方法
    }


    Console.WriteLine("实例化Person,并调用SayHello方法");
    //Activator在远程或本地创建实例
    //CreateInstance 使用指定类型默认构造
    object obj = Activator.CreateInstance(Person); //没有传参的构造
    object objName = Activator.CreateInstance(Person, "我把叫李刚");//有传参的构造

    MethodInfo MsSayHello = Person.GetMethod("SayHello");
    MsSayHello.Invoke(obj, null); //空的实例传参数
    MsSayHello.Invoke(objName, null); //带参数构造实例

    Console.Read();
    }
    }
    }

    结果如下

    四、多继承

    请允许我偷哈懒扣了2张图

    下面实现一个派生类的接口继承

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

    namespace 派生类的接口继承
    {
    class Program
    {
    interface IFace
    {
    void Say();
    void Hello();
    }
    //派生类继承接口 接口可以被多次继承
    class FacetoFace : IFace
    {
    public void Say()
    {
    Console.WriteLine("这是继承IFace的Say方法");
    }
    public void Hello()
    {
    Console.WriteLine("IFace Hello World!");
    }
    }
    static void Main(string[] args)
    {
    FacetoFace facetoface = new FacetoFace();
    facetoface.Say();
    facetoface.Hello();
    Console.ReadKey();
    }
    }
    }

    五、隐藏基类

     有的时候同一个功能需要重新在派生类中实现新的逻辑,而不想用基类的方法

    即隐藏掉父类的成员方法,c#使用new修改师傅来实现隐藏基类成员

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

    namespace 隐藏基类
    {
    public class Parent
    {
    public Parent()
    {
    Console.WriteLine("父类的构造函数");
    }
    public void SayHello()
    {
    Console.WriteLine("我是父类");
    }
    }
    public class Child:Parent
    {
    public Child()
    {
    Console.WriteLine("我是子类");
    }
    public new void SayHello() //添加了new
    {
    Console.WriteLine("我是子类,你老了你改退休了");
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    Child child = new Child();
    child.SayHello();
    Console.Read();
    }
    }
    }

    六、使用abstract多态

    //c#中通过把类或者方法声明位abstract来实现抽象类和抽象方法,抽象类不能实例化,
    //抽象方法没有具体执行代码,必须在非抽象的派生类中重写

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

    namespace abstract派生类
    {

    class Program
    {
    public abstract class Parent
    {
    public Parent()
    {
    Console.WriteLine("父类的构造函数");
    }
    abstract public void SayHello();

    }
    public class Child : Parent
    {
    public Child()
    {
    Console.WriteLine("我是子类");
    }
    public override void SayHello()
    {
    Console.WriteLine("我是子类,你老了你改退休了");
    }
    }
    static void Main(string[] args)
    {
    Child child = new Child();
    child.SayHello();
    }
    }
    }

    七、使用virtual派生对象

    //如果不想把类声明位抽象类,单有想实现方法在基中不具体实现,而是在派生类中重新实现功能,该怎么办呢?
    //可以通过把方法声明位虚函数virtual的形式来实现方法的重写,可以不重写调用virtual的方法

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

    namespace 使用virtual多态
    {

    public class Parent
    {
    public Parent()
    {
    Console.WriteLine("父类的构造函数");
    }
    public virtual void SayHello1()
    {

    }
    public virtual void SayHello2(string name)
    {
    //虚函数必须方法主题,抽象方法可以不需要
    //打起 "{}"表示声明了也可以不写也可以写
    //我这儿还是写了
    Console.WriteLine("Hello,{0}!", name);

    }

    }
    public class Child : Parent
    {
    public Child()
    {
    Console.WriteLine("我是子类");
    }
    public override void SayHello1() //实现了多态重写了接口
    {
    Console.WriteLine("我是子类,你老了你改退休了");

    }
    public void Hello() //这儿实现了调用虚方法
    {
    SayHello2("张三");
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    Child child = new Child();
    child.SayHello1();
    child.Hello();
    Console.ReadKey();
    }
    }
    }

    八、密封类

    //如果所有的类都可以被继承,那么继承的泛滥,类的层次结构体系
    //变得非常庞大,大类之间的关系杂乱无章,对类的理解和使用都会变得困难
    //所以提供了密封类的概念(sealed class)的改了,帮助开发人员来解决这一问题。
    //使用sealed修饰符,这个可以放在该类被其他类继承,如果继承那么久会报错

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

    namespace 密封类
    {

    class Program
    {
    sealed class Parent
    {
    public Parent()
    {
    Console.WriteLine("父类构造函数");
    }
    public void Hello()
    {
    Console.WriteLine("我是父类");
    }
    }
    //public class Child:Parent //这儿会报错
    //{

    //}
    static void Main(string[] args)
    {
    }
    }
    }

    九、using 关键字的几种用途?

    一共有3种

    第一种:using 命名空间的名字;    引用命名空间

    例如:using System;

    第二种:using别名

    第三种:释放资源

    十、#waring和#error分别的用途是什么?

    十一、Asp.Net web应用程序和Asp.NET网站的区别是什么?

    咱家后面偷懒了,所以你懂的,这是我第三次写”博客“,如果有问题,”请指教“

    如果想骂我

  • 相关阅读:
    Vue路由和组件分别在什么场景使用
    mybatis返回集合对象包含List<String>
    vue登录页+验证码+MD5加密
    mybatis 查询树形结构
    解决Vue Router报错 Error: Cannot find module ‘@/views/xxx‘ at webpackEmptyContext
    HttpServletRequest 在Filter中添加header
    CRM体系中的SFA(SaleForce Automation)应该怎么设计?
    Google Analytics Advertisement 广告 URL : 数据产品知识 UTM
    Win11要的TPM 2.0不一定是独立芯片,你的CPU固件可能已经支持 || 杨澜对话尹志尧:美国顶尖半导体专家华人很多,国内却奇缺
    mysql SQL注入攻击 解决Orm工具Hibernate,Mybatis, MiniDao 的 sql 预编译语句 ;解决非Orm工具JDBCTemplate的
  • 原文地址:https://www.cnblogs.com/XiaoGuanYu/p/7495360.html
Copyright © 2020-2023  润新知