【理解】C# 委托与事件、随机生成数与计时器

19.10.21

今日份学习知识点

委托类型(Delegate Type)用于定义一个从 System.Delegate 类派生的类型,其功能与 C++ 语言中指向函数的指针功能类似,不同的是 C++ 语言的函数指针只能够指向静态的方法,而委托除了可以指向静态的方法之外,还可以指向实例的方法。
特点:任何类或对象中的方法都可以通过委托来调用,唯一要求:方法参数类型和返回类型必须与委托的一致。
通过委托,可将方法作为实体赋值给变量
———————————————————
事件(Event)是一种使类或对象能够提供通知的成员,本质上是利用委托来实现的。
要在应程序中自定义和引发事件,必须提供一个事件处理程序(事件处理方法),以便与事件关联的委托能自动调用它。

DT.cs(DelegateTest)

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

namespace HLclassTest
{
    //1.先定义一个委托类型
    public delegate double MyFunc(double d);
    class DT
    {
        //2.声明同格式方法
        double Mul(double x)
        {
            return x * x;
        }

        double Abs(double x)
        {
            return Math.Abs(x);     //Math类中有好多方法可以用,这个是求绝对值
        }

        //4.遍历输出(这是两个嵌套的foreach,每从委托中遍历到一个函数,就遍历数组,并将每一个数组元素用函数执行)
        public void Output(double[] a,MyFunc func)
        {
            foreach(var item in a)  //foreach遍历数组a
            {
                Console.WriteLine(func(item));  //从a中得到的值用此时遍历到的函数执行
            }
        }

        internal void Output(double[] a)    //方法重载
        {
            //3.把方法放入到委托当中
            MyFunc[] myFuncs = new MyFunc[] { Mul, Abs };

            foreach(var item in myFuncs)    //从委托中遍历方法
            {
                Output(a, item);    //调用上面的两个参数的Output方法
            }
        }
    }
}

ET.cs(EventTest)

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

namespace HLclassTest
{
    class ET
    {
        //1.事件是利用委托来实现的,先定义一个委托
        public delegate void MyEventHandler(string name);

        //2.用 event 关键字声明事件
        public event MyEventHandler Handler;

        //3.定义引发事件时要调用的方法
        public void CollegeRoad()
        {
            Handler(_name);     //此时_name是构造方法中传入的参数“Panda”
        }

        //4.用构造方法注册事件( -= 是取消事件)
        string _name;
        public ET(string name)
        {
            _name = name;
            this.Handler += Baby;   //这几个函数名是在定义函数之后才合法的,通过委托,可将方法作为实体赋值给变量
            this.Handler += SchoolTime;
            this.Handler += College;
        }

        public void College(string name)
        {
            Console.WriteLine(name + ":Wao,time to go to college!");
        }

        public void SchoolTime(string name)
        {
            Console.WriteLine(name + ";Yes, time to go to school!");
        }

        public void Baby(string name)
        {
            Console.WriteLine(name + ":Little baby is born!");
        }
    }
}

Program.cs

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

namespace HLclassTest
{
    class Program
    {
        static void Main(string[] args)
        {
            double[] a = { 12, -31, -434, -123 };   //定义并给数组a赋初值
            DT dt = new DT();
            dt.Output(a);   //调用相应的只有一个参数的函数

            ET et = new ET("Panda");
            et.CollegeRoad();

            Console.ReadKey();
        }
    }
}

在这里插入图片描述

19.10.24 By Myself(自己实现)

自己实现
By Myself

DeleTest.cs

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

namespace ConsoleApp1
{
    class DeleTest
    {
        public delegate void Dele(string name);

        string _name;

        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                Operation(_name);
            }
        }

        public DeleTest(string name)
        {
            Name = name;
        }

        public void Operation(string name)
        {
            Dele[] dele = new Dele[] { Bagin, Speed, Victory };
            foreach (var item in dele)
            {
                item(name);
            }
        }

        public void Bagin(string name)
        {
            Console.WriteLine(name + "启动!");
        }

        public void Speed(string name)
        {
            Console.WriteLine(name + "加速!");
        }

        public void Victory(string name)
        {
            Console.WriteLine(name + "胜利!");
        }
    }
}

EventTest.cs

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

namespace ConsoleApp1
{
    class EventTest
    {
        public delegate void Dele(string name);     //写在类中或者是命名空间里都行
        public event Dele Handler;

        string _name;

        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                Handler(value);
            }
        }

        public EventTest(string name)
        {
            //Dele[] dele = new Dele[] { Bagin, Speed, Victory };不用了
            Handler += Bagin;
            Handler += Speed;
            Handler += Victory;
            Name = name;
        }

        public void Bagin(string name)
        {
            Console.WriteLine(name + "启动!");
        }

        public void Speed(string name)
        {
            Console.WriteLine(name + "加速!");
        }

        public void Victory(string name)
        {
            Console.WriteLine(name + "胜利!");
        }
    }
}

Program.cs

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            EventTest eventTest = new EventTest("ZhanLang");

            DeleTest deleTest = new DeleTest("ChuanShuo");
            Console.ReadKey();
        }
    }
}

运行结果:
在这里插入图片描述

Form1.cs(利用计时器生成随机数)

利用计时器生成随机数

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;   //导入后才能用Stopwatch

namespace TimeTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Stopwatch _stopwatch = new Stopwatch(); //用于准确测量运行时间
        Random _random = new Random();      //先创建一个random的对象,后面用来调用Next,返回范围内的任意整数
        int _sec = 3;
        private void button1_Click(object sender, EventArgs e)
        {
            this.timerNum.Enabled = !this.timerNum.Enabled;     //若计时器关闭,则运行
            this.timerBar.Enabled = this.timerNum.Enabled;      //将timerBar的计时器状态与Num的保持一致

            if(this.timerNum.Enabled == true)
            {
                this.button1.Text = "正在生成";
                _stopwatch.Restart();   //重新测量运行时间
            }
            else
            {
                this.button1.Text = "生成";
                _stopwatch.Stop();  //停止测量运行时间
            }
        }

        private void timerNum_Tick(object sender, EventArgs e)
        {
            this.label3.Text = _stopwatch.Elapsed.ToString();   //获取运行时间

            this.textBox1.Clear();      //将之前生成的随机数清空
            for (int i = 0; i < 5; i++)
            {
                this.textBox1.Text += _random.Next(100) + " ";  //循环生成0~100的随机数
            }

            _sec = _random.Next(1, 5);  //将生成随机数的时间也设成1~5之间随机的
            this.timerNum.Interval = _sec * 1000;
            this.label1.Text = "每隔" + _sec + "秒生成5个随机数";

            _stopwatch.Restart();   //重新测量时间
        }

        private void timerBar_Tick(object sender, EventArgs e)
        {
            this.progressBar1.Value = (int)_stopwatch.ElapsedMilliseconds / (10 * _sec);    //获取进度条当前位置?
            this.progressBar1.PerformStep();    //让进度条跑到头
            //this.progressBar1.PerformStep();    //事实证明,这条语句有用,进度条跑的更接近尽头...
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }	//双击点开之后,即使不用,也不要删除。。。
    }
}

运行结果:
在这里插入图片描述

19.10.27

Form1.cs

利用计时器和随机数以及委托计算一个数的三角函数、绝对值和平方

要求:
1.三角函数的输入是double型的,返回也是double型的,一次计算四个,用委托完成。
2.把刚刚的数字转为int型的,并利用事件计算绝对值和平方。
3.输入在窗体中的TextBox中,计算结果在窗体的RichTextBox中显示。
4.在完成第一次输入后,后面的数是随机生成的,范围是[-180~360]
5.每隔随机秒输出一次结果。并且记录下生成的时间,年月日时分秒
6.有进度条显示目前执行情况

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace WindowsFormsApp1
{
    public delegate double Dele(double num);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Stopwatch _stopwatch = new Stopwatch();
        Random _random = new Random();
        int _sec = 3;
        double _num = 0;
        double _pnum = 0;

        /*public void Operation(double num)
        {
            Dele[] dele = new Dele[] { Sin, Cos, Tan };
            foreach(var item in dele)
            {
                item(num);
            }
        }*/

        public double Sin(double num)
        {
            return Math.Sin(num);
        }

        public double Cos(double num)
        {
            return Math.Cos(num);
        }

        public double Tan(double num)
        {
            return Math.Tan(num);
        }

        public double Cot(double num)
        {
            return 1 / Math.Tan(num);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.timerNum.Enabled = !this.timerNum.Enabled;
            this.timerBar.Enabled = this.timerNum.Enabled;

            if(this.timerNum.Enabled == true)
            {
                this.button1.Text = "正在生成";
                _stopwatch.Restart();
            }
            else
            {
                this.button1.Text = "生成";
                _stopwatch.Stop();
            }
        }

        private void timerNum_Tick(object sender, EventArgs e)
        {
            this.labeltime.Text = "data:"+DateTime.Now.ToString()+" ruantime:"+_stopwatch.Elapsed.ToString();

            this.richTextBox1.Clear();
            this.richTextBox2.Clear();
            this.richTextBox3.Clear();

            _num = double.Parse(this.textBox1.Text);

            Dele[] dele = new Dele[] { Sin, Cos, Tan, Cot };
            this.richTextBox1.Text = dele[0](_num).ToString();
            this.richTextBox2.Text = dele[1](_num).ToString();
            this.richTextBox3.Text = dele[2](_num).ToString();
            this.richTextBox6.Text = dele[3](_num).ToString();
            int num = (int)_num;
            this.richTextBox4.Text = Math.Abs(num).ToString();
            this.richTextBox5.Text = (num * num).ToString();

            _pnum = _num;
            this.textBox2.Text = _pnum.ToString();
            _num = _random.Next(-180, 360);
            this.textBox1.Text = _num.ToString();

            _sec = _random.Next(1, 5);
            this.timerNum.Interval = _sec * 1000;
            this.label5.Text = _sec+"秒生成-180到360之间的随机数";

            _stopwatch.Restart();
        }

        private void progressBar1_Click(object sender, EventArgs e)      //这句中的Tick点进来时是Click,注意哦
        {
            //好像搞错了。。。
        }

        private void timerBar_Tick(object sender, EventArgs e)
        {

            this.progressBar1.Value = (int)_stopwatch.ElapsedMilliseconds / (10 * _sec);
            this.progressBar1.PerformStep();    //这句可以不用
        }
    }
}

运行结果:
在这里插入图片描述



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值