c# 委托 事件 lambda表达式

news2024/11/29 5:37:44

委托

C/C++中的函数指针实例:

typedef int (*Calc)(int a, int b); //这里必须加括号
int Add(int a, int b)
{
    return a + b;
}
int Sub(int a, int b)
{
    return a - b;
}
int main()
{
    int x = 100;
    int y = 200;
    int z = 0;
    Calc funcPoint1 = &Add;
    Calc funcPoint2 = ⋐
    z = funcPoint1(x, y);
    cout << z << endl;
    z = funcPoint2(x, y);
    cout << z << endl;
}

委托实例

class Program
    {
        
        static void Main(string[] args)
        {
            Calculator c = new Calculator();
            //Action委托:没有返回参数
            Action action = new Action(c.PrintInfo);
            c.PrintInfo();
            action.Invoke();
            action();
            //Func委托:有返回参数
            Func<int, int, int> f = new Func<int, int, int>(c.Add);
            Func<int, int, int> f2 = new Func<int, int, int>(c.Sub);
            
            Console.WriteLine(f(1, 2));
            Console.WriteLine(f.Invoke(1, 2));
            Console.WriteLine(f2(1, 2));
            Console.WriteLine(f2.Invoke(1, 2));
        }
        

    }
    class Calculator
    {
        public void PrintInfo()
        {
            Console.WriteLine("this class has 3 methods");
        }
        public int Add(int a, int b)
        {
            return a + b;
        }
        public int Sub(int a, int b)
        {
            return a - b;
        }
    }
class Program
{
    static void Main(string[] args)
    {
        Action<string> action = new Action<string>(SayHello);
        action("Tim");
    }
    static void SayHello(string name)
    {
        Console.WriteLine($"Hello, {name1}!");
	
    }
}
//可以用var关键字来缩短代码:
class Program
{
    static void Main(string[] args)
    {
        var action = new Action<string, int>(SayHello);
        action("Tim");
    }
    static void SayHello(string name, int rount)
    {
      	for(int i=0; i<round; ++i)
      	{
        	Console.WriteLine($"Hello, {name1}!");
        }

    }
}

Console.WriteLine后面 “$”的作用

//复杂麻烦的写法
        string str1 = "my name is " + name + ",my age is " + age + ".";
        //使用Format的写法
        string str2 = string.Format("my name is {0},my age is {1}.", name, age);
        //使用$语法糖的写法
        string str3 = $"my name is {name},my age is {age}.";

public delegate double Calc(double x, double y);
    class Program
    {
        
        static void Main(string[] args)
        {
            Calculator calculator = new Calculator();
            double x = 200;
            double y = 100;
            double z;
            Calc calc1 = new Calc(calculator.Add);
            Calc calc2 = new Calc(calculator.Sub);
            Calc calc3 = new Calc(calculator.Mul);
            Calc calc4 = new Calc(calculator.Div);
            z = calc1(x, y);
            Console.WriteLine(z);
            z = calc2.Invoke(x, y);
            Console.WriteLine(z);
            z = calc3.Invoke(x, y);
            Console.WriteLine(z); 
            z = calc4.Invoke(x, y);
            Console.WriteLine(z);
        }
        

    }
    class Calculator
    {
        
        public double Add(double a, double b)
        {
            return a + b;
        }
        public double Sub(double a, double b)
        {
            return a - b;
        }
        public double Mul(double a, double b)
        {
            return a * b;
        }
        public double Div(double a, double b)
        {
            return a / b;
        }
    }

模板方法案例

class Program
{
    
    static void Main(string[] args)
    {
        ProductFactory pf = new ProductFactory();
        WrapFactory wf = new WrapFactory();
        Func<Product> func1 = new Func<Product>(pf.MakePizza);
        Func<Product> func2 = new Func<Product>(pf.MakeToyCar);

        Box box1 = wf.WrapProduct(func1);
        Box box2 = wf.WrapProduct(func2);
        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);

    }
}
class Product
{
    public string Name { get; set; }
}
class Box
{
    public Product Product { get; set; }
}
class WrapFactory
{
    public Box WrapProduct(Func<Product> getProduct)
    {
        Box box = new Box();
        box.Product = getProduct.Invoke();
        return box;
    }
}
class ProductFactory
{
    public Product MakePizza()
    {
        Product product = new Product();
        product.Name = "Pizza";
        return product;
    }
    public Product MakeToyCar()
    {
        Product product = new Product();
        product.Name = "Toy Car";
        return product;
    }
}

回调方法案例

class Program
{
    
    static void Main(string[] args)
    {
        ProductFactory pf = new ProductFactory();
        WrapFactory wf = new WrapFactory();
        Func<Product> func1 = new Func<Product>(pf.MakePizza);
        Func<Product> func2 = new Func<Product>(pf.MakeToyCar);
        Logger logger = new Logger();
        Action<Product> action = new Action<Product>(logger.log);
        Box box1 = wf.WrapProduct(func1, action);
        Box box2 = wf.WrapProduct(func2, action);
        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);

    }
}
class Logger
{
    public void log(Product product)
    {
        Console.WriteLine("Product {0} created at {1}. Price is {2}.", product.Name, DateTime.UtcNow, product.Price); 
    }
}
class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}
class Box
{
    public Product Product { get; set; }
}
class WrapFactory
{
    public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback)
    {
        Box box = new Box();
        Product product = getProduct.Invoke();
        if(product.Price>=50)
        {
            logCallback.Invoke(product);
        }
        box.Product = product;
        return box;
    }
}
class ProductFactory
{
    public Product MakePizza()
    {
        Product product = new Product();
        product.Name = "Pizza";
        product.Price = 12;
        return product;
    }
    public Product MakeToyCar()
    {
        Product product = new Product();
        product.Name = "Toy Car";
        product.Price = 100;
        return product;
    }
}

委托的高级使用

多播委托案例

class Program
{

    static void Main(string[] args)
    {
        Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};
        Student stu2 = new Student() { ID=1, PenColor = ConsoleColor.Green};
        Student stu3 = new Student() { ID=1, PenColor = ConsoleColor.Red};
        Action action1 = new Action(stu1.DoHomeWork);
        Action action2 = new Action(stu2.DoHomeWork);
        Action action3 = new Action(stu3.DoHomeWork);
        //单播委托
        //action1.Invoke();
        //action2.Invoke();
        //action3.Invoke();
        //多播委托
        action1 += action2;
        action1 += action3;
        action1.Invoke();
    }
}
class Student
{
    public int ID { get; set; }
    public ConsoleColor PenColor { get; set; }
    public void DoHomeWork()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.ForegroundColor = this.PenColor;
            Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);
            Thread.Sleep(1000);
        }
    }
}

隐式异步调用 -- BeginInvoke

class Program
{

    static void Main(string[] args)
    {
        Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};
        Student stu2 = new Student() { ID=2, PenColor = ConsoleColor.Green};
        Student stu3 = new Student() { ID=3, PenColor = ConsoleColor.Red};
        Action action1 = new Action(stu1.DoHomeWork);
        Action action2 = new Action(stu2.DoHomeWork);
        Action action3 = new Action(stu3.DoHomeWork);
        //隐式异步调用
        action1.BeginInvoke(null, null);
        action2.BeginInvoke(null, null);
        action3.BeginInvoke(null, null);
        for (int i = 0; i < 10; i++)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("Main thread {0}.", i);
            Thread.Sleep(1000);
        }

    }
}
class Student
{
    public int ID { get; set; }
    public ConsoleColor PenColor { get; set; }
    public void DoHomeWork()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.ForegroundColor = this.PenColor;
            Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);
            Thread.Sleep(1000);
        }
    }
}

显式异步调用

注:ctrl+. 给没有定义命名空间的类添加命名空间

class Program
    {

        static void Main(string[] args)
        {
            Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};
            Student stu2 = new Student() { ID=2, PenColor = ConsoleColor.Green};
            Student stu3 = new Student() { ID=3, PenColor = ConsoleColor.Red};

            //显式异步调用

            Thread thread1 = new Thread(new ThreadStart(stu1.DoHomeWork));
            Thread thread2 = new Thread(new ThreadStart(stu2.DoHomeWork));
            Thread thread3 = new Thread(new ThreadStart(stu3.DoHomeWork));
            thread1.Start();
            thread2.Start();
            thread3.Start();

          	//使用task显式异步调用
						Action action1 = new Action(stu1.DoHomeWork);
            Action action2 = new Action(stu2.DoHomeWork);
            Action action3 = new Action(stu3.DoHomeWork);
          	Task task1 = new Task(action1);
            Task task2 = new Task(action2);
            Task task3 = new Task(action3);
            task1.Start();
            task2.Start();
            task3.Start();

            for (int i = 0; i < 10; i++)
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("Main thread {0}.", i);
                Thread.Sleep(1000);
            }

        }
    }
    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor { get; set; }
        public void DoHomeWork()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.ForegroundColor = this.PenColor;
                Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);
                Thread.Sleep(1000);
            }
        }
    }

可以使用接口来取代委托

以上面的回调方法中的例子作为改进:

class Program
{

    static void Main(string[] args)
    {
        IProductFactory pizzaFactory = new PizzaFactory();
        IProductFactory toycarFactory = new ToycarFactory();
        WrapFactory wf = new WrapFactory();
        
        Box box1 = wf.WrapProduct(pizzaFactory);
        Box box2 = wf.WrapProduct(toycarFactory);
        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);

    }
}
interface IProductFactory
{
    Product Make();
}
class PizzaFactory : IProductFactory
{
    public Product Make()
    {
        Product product = new Product();
        product.Name = "Pizza";
        product.Price = 12;
        return product;
    }
}
class ToycarFactory : IProductFactory
{
    public Product Make()
    {
        Product product = new Product();
        product.Name = "Toy Car";
        product.Price = 100;
        return product;
    }
}
class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}
class Box
{
    public Product Product { get; set; }
}
class WrapFactory
{
    public Box WrapProduct(IProductFactory productFactory)
    {
        Box box = new Box();
        Product product = productFactory.Make();
        box.Product = product;
        return box;
    }
}

自己定义委托类型

class Program
{

    static void Main(string[] args)
    {
        MyDele dele1 = new MyDele(M1);
      	Student stu = new Student();
      	//dele1 += stu.SayHello;
      	//同上
				dele1 += (new Studnet()).SayHello;
      	//dele1.Invoke();
      	//同上,与上面相比下面直接调用方法更常用。
      	dele1();
    }
  	static void M1()
  	{
    	Console.Write("M1 is called");
    }
  	class Student{
    	public void SayHello(){
      	Concole.WriteLine("Hello, I'm a student!");
    	}
  	}
  	delegate void MyDele();
}

自定义泛型委托

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

namespace DelegateExample
{
    class Program
    {
        static void Main(string[] args)
        {
            MyDele<int> myDele = new MyDele<int>(Add);
            int addRed = myDele(2, 4);
            Console.WriteLine(addRed);
            MyDele<double> myDele2 = new MyDele<double>(Mul);
            double mulRed = myDele2(2.2, 2.2);
            Console.WriteLine(mulRed);
            //查看委托是否是类
            Console.WriteLine(myDele.GetType().IsClass);
        }
        static int Add(int x, int y)
        {
            return x + y;
        }
        static double Mul(double x, double y)
        {
            return x * y;
        }
    }
    delegate T MyDele<T>(T a, T b);
}

事件

事件的概念

微软把这种经由事件发送出来的与事件本身相关的数据称为:事件参数

根据通知和事件参数来采取行动的这种行为称为响应事件或处理事件。处理事件时具体所做的事情就叫做事件处理器

事件的应用

案例1.
class Program
    {
        static void Main(string[] args)
        {
            //timer: 事件的拥有者
            Timer timer = new Timer();
            timer.Interval = 1000;
            // boy和girl: 事件的响应者
            Boy boy = new Boy();
            //timer.Elapsed: 事件成员; boy.Action: 事件处理器;+=: 事件订阅
            timer.Elapsed += boy.Action;
            Girl girl = new Girl();
            timer.Elapsed += girl.Action;
            //timer.Enabled = true;
            timer.Start();
            Console.ReadLine();

        }
    }
    class Boy
    {
        internal void Action(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("jump");
        }
    }
    class Girl
    {
        internal void Action(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("Sing");
        }
    }
案例2:图一颗星方式
class Program
    {
        static void Main(string[] args)
        {
            //form: 事件拥有者
            Form form = new Form();
            //controller: 事件响应者
            Controller controller = new Controller(form);
            form.ShowDialog();
        }
    }
    class Controller
    {
        private Form form;
        public Controller(Form form)
        {
            this.form = form;
            //this.form.Click: 事件; +=: 事件订阅
            this.form.Click += this.FormClicked;
        }
        //FormClicked:事件处理器
        private void FormClicked(object sender, EventArgs e)
        {
            this.form.Text = DateTime.Now.ToString();
        }
    }
案例3:图两颗星方式
class Program
    {
        static void Main(string[] args)
        {
            //form: 事件拥有者和响应者
            MyForm form = new MyForm();
            form.Click += form.FormClicked;
            form.ShowDialog();
        }
    }
    class MyForm : Form
    {
        internal void FormClicked(object sender, EventArgs e)
        {
            this.Text = DateTime.Now.ToString();
        }
    }
案例4:图三颗星方式
class Program
    {
        static void Main(string[] args)
        {
            //form: 事件拥有者和响应者
            MyForm form = new MyForm();        
            form.ShowDialog();
        }
    }
    this Form: 响应者
    class MyForm : Form
    {
        private TextBox textBox;
        private Button button;
        public MyForm()
        {
            this.textBox = new TextBox();
            //this.button: 拥有者
            this.button = new Button();
            this.Controls.Add(this.textBox);
            this.Controls.Add(this.button);
            this.button.Click += this.ButtonClicked;
            this.button.Text = "say hello";
            this.button.Top = 50;
        }

        public void ButtonClicked(object sender, EventArgs e)
        {
            this.textBox.Text = "Hello World!!!!!!!!!!!!!!!!!!";
        }
    }
在窗体应用程序中,使用事件的五种方法
namespace EventWindowsForms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //button2. 方法2. 手动订阅
            this.button2.Click += buttonClick;
            //button3. 方法3.委托
            this.button3.Click += new EventHandler(buttonClick);
            //button4. 方法4. 旧式委托
            this.button4.Click += delegate (object sender, EventArgs e)
              {
                  this.myTextBox.Text = "button4Clicked!";
              };
            //button5. 方法5. lambda表达式
            this.button5.Click += (sender, e) =>
              {
                  this.myTextBox.Text = "button5Clicked!";
              };
        }

        //button1. 方法1.直接在设计中双击click自动生成订阅
        private void buttonClick(object sender, EventArgs e)
        {
            if(sender==button1)
            {
                this.myTextBox.Text = "hello!";
            }
            if(sender==button2)
            {
                this.myTextBox.Text = "world!";
            }
            if(sender==button3)
            {
                this.myTextBox.Text = "My.Okey!";
            }
        }
    }
}

事件的定义

事件声明的完整格式

namespace FullFormOfEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Waiter waiter = new Waiter();
            customer.Order += waiter.Action;
            //一定是事件拥有者的内部逻辑触发了该事件
            customer.Action();
            customer.PayThisBill();
        }

        
    }

    public class OrderEventArgs:EventArgs
    {
        public string DishName { get; set; }
        public string Size { get; set; }
    }

    //声明委托类型 为声明的order事件用的
    //当一个委托专门用来声明事件时,名称一般为事件名+EventHandler
    public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);

    public class Customer
    {
        //声明一个委托类型的字段 引用事件处理器的
        private OrderEventHandler orderEventHandler;

        public event OrderEventHandler Order
        {
            add
            {
                this.orderEventHandler += value;
            }
            remove
            {
                this.orderEventHandler -= value;
            }
        }

        public double Bill { get; set; }
        public void PayThisBill()
        {
            Console.WriteLine("I will pay ${0}.", this.Bill);
        }
        //事件要通过委托来做一个约束,这个委托
        //既规定了事件发送什么消息给事件的响应者
        //也规定了事件的响应者能收到什么样的消息
        //事件响应者的事件处理器必须能够跟约束匹配上,才能订阅事件
        //当事件的响应者向事件的拥有者提供了能够匹配这个事件的事件处理器之后,
        //需要将此处理器保存或记录下来,能够记录或引用方法的任务只有
        //引用委托的实例才能够做到。

        //事件这种成员,无论从表层约束上来讲,还是从底层实现来讲,都依赖委托类型

        public void WalkIn()
        {
            Console.WriteLine("Walk into the restaurant.");
        }
        public void SitDown()
        {
            Console.WriteLine("Sit down.");
        }
        public void Think()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Let me think。。。");
                Thread.Sleep(1000);

            }
            if(this.orderEventHandler!=null)
            {
                OrderEventArgs e = new OrderEventArgs();
                e.DishName = "Kongpao Chicken";
                e.Size = "large";
                this.orderEventHandler.Invoke(this, e);
            }
        }
        public void Action()
        {
            Console.ReadLine();
            this.WalkIn();
            this.SitDown();
            this.Think();

        }


    }
    public class Waiter
    {
        internal void Action(Customer customer, OrderEventArgs e)
        {
            Console.WriteLine("I will serve you the dish - {0}.", e.DishName);
            double price = 10;
            switch (e.Size)
            {
                case "small":
                    price = price * 0.5;
                    break;
                case "large":
                    price = price * 1.5;
                    break;
                default:
                    break;
            }
            customer.Bill += price;
        }
    }
}

事件声明的简略格式

只修改了两个部分

namespace FullFormOfEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Waiter waiter = new Waiter();
            customer.Order += waiter.Action;
            //一定是事件拥有者的内部逻辑触发了该事件
            customer.Action();
            customer.PayThisBill();
        }
    }

    public class OrderEventArgs:EventArgs
    {
        public string DishName { get; set; }
        public string Size { get; set; }
    }

    //声明委托类型 为声明的order事件用的
    //当一个委托专门用来声明事件时,名称一般为事件名+EventHandler
    public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
    public class Customer
    {
// 修改1
        public event OrderEventHandler Order;

        public double Bill { get; set; }
        public void PayThisBill()
        {
            Console.WriteLine("I will pay ${0}.", this.Bill);
        }
        public void WalkIn()
        {
            Console.WriteLine("Walk into the restaurant.");
        }
        public void SitDown()
        {
            Console.WriteLine("Sit down.");
        }
        public void Think()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Let me think。。。");
                Thread.Sleep(1000);
            }
//修改2
            //和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字
            //之前的委托类型字段还在,只不过没有出现在代码中
            if(this.Order!=null)
            {
                OrderEventArgs e = new OrderEventArgs();
                e.DishName = "Kongpao Chicken";
                e.Size = "large";
                this.Order.Invoke(this, e);
            }
        }
        public void Action()
        {
            Console.ReadLine();
            this.WalkIn();
            this.SitDown();
            this.Think();

        }
    }
    public class Waiter
    {
        internal void Action(Customer customer, OrderEventArgs e)
        {
            Console.WriteLine("I will serve you the dish - {0}.", e.DishName);
            double price = 10;
            switch (e.Size)
            {
                case "small":
                    price = price * 0.5;
                    break;
                case "large":
                    price = price * 1.5;
                    break;
                default:
                    break;
            }
            customer.Bill += price;
        }
    }
}

省去了委托类型的声明,而是使用了通用的EventHandler

namespace FullFormOfEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Waiter waiter = new Waiter();
            customer.Order += waiter.Action;
            //一定是事件拥有者的内部逻辑触发了该事件
            customer.Action();
            customer.PayThisBill();
        }

        
    }
    public class OrderEventArgs:EventArgs
    {
        public string DishName { get; set; }
        public string Size { get; set; }
    }
    public class Customer
    {
        //省去了委托类型的声明,而是使用了通用的EventHandler
        public event EventHandler Order;

        public double Bill { get; set; }
        public void PayThisBill()
        {
            Console.WriteLine("I will pay ${0}.", this.Bill);
        }
	      public void WalkIn()
        {
            Console.WriteLine("Walk into the restaurant.");
        }
        public void SitDown()
        {
            Console.WriteLine("Sit down.");
        }
        public void Think()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Let me think。。。");
                Thread.Sleep(1000);

            }
            //和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字
            //之前的委托类型字段还在,只不过没有出现在代码中
            if(this.Order!=null)
            {
                OrderEventArgs e = new OrderEventArgs();
                e.DishName = "Kongpao Chicken";
                e.Size = "large";
                this.Order.Invoke(this, e);
            }
        }
        public void Action()
        {
            Console.ReadLine();
            this.WalkIn();
            this.SitDown();
            this.Think();

        }
    }
    public class Waiter
    {
        internal void Action(Object sender, EventArgs e)
        {
            Customer customer = sender as Customer;
            OrderEventArgs orderInfo = e as OrderEventArgs;
            Console.WriteLine("I will serve you the dish - {0}.", orderInfo.DishName);
            double price = 10;
            switch (orderInfo.Size)
            {
                case "small":
                    price = price * 0.5;
                    break;
                case "large":
                    price = price * 1.5;
                    break;
                default:
                    break;
            }
            customer.Bill += price;
        }
    }
}

事件与委托的关系

lambda表达式

是匿名和inline方法

//lambda表达式:方法1
Func<int, int, int> func = new Func<int, int, int>((int a, int b)=> { return a + b; });
int res = func(3, 5);
Console.WriteLine($"a+b={res}");
//方法2
func = new Func<int, int, int>((x, y) => { return x * y; });
res = func(3, 5);
Console.WriteLine($"a*b={res}");
//方法3 最常用
func = (x, y) => { return x - y; };
res = func(3, 5);
Console.WriteLine($"a-b={res}");

使用函数来调用lambda表达式(泛型委托的类型参数推断)

DoSomeCalc((a, b)=> { return a + b; }, 100, 200);
static void DoSomeCalc<T>(Func<T, T, T>func, T x, T y)
{
    T res = func(x, y);
    Console.WriteLine(res);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【实践成果】Splunk 9.0 Configuration Change Tracking

Splunk 9.0 引入了新的功能&#xff0c;一个很重要的一个&#xff0c;就是跟踪conguration 文件的变化&#xff1a; 这个很重要的特性&#xff0c;在splunk 9.0 以后才引入&#xff0c;就看server.conf 配置中&#xff0c;9.0 以后的版本才有&#xff1a; server.conf - Splu…

【STL巨头】set、map、multiset、multimap的介绍及使用

set、map、multiset、multimap的介绍及使用 一、关联式容器二、键值对键值对概念定义 三、setset的介绍set的使用set的模板参数列表set的构造set的迭代器set的容量emptysize set的修改操作insertfind && erasecountlower_bound 和 upper_bound Multiset的用法 四、mapm…

WebGL笔记:绘制矩形面的几种方式以及封装封装多边形对象来绘制不同图形

绘制矩形面 可以绘制的面只有三角面&#xff0c;要绘制矩形面的话&#xff0c;只能用两个三角形去拼 1 &#xff09; 使用 三角带 TRIANGLE_STRIP 绘制矩形 回顾一下之前的规律&#xff1a; 第一个三角形&#xff1a;v0>v1>v2第偶数个三角形&#xff1a;以上一个三角形…

预编译(2)

#和## #运算符&#xff1a; #运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执⾏的操作可以理解为“字符串化”。 举例&#xff1a; 当我们有⼀个变量 int a 10; 的时候&#xff0c;我们想打印出&#xff1a; the value of …

volatile修饰数组

结论&#xff1a;volatile修饰对象或数组时&#xff0c;只能保证他们的引用地址的可见性。 非volatile数组的可见性问题 public class Test {static int[] a new int[]{1};public static void main(String[] args) {new Thread(() -> { //线程Atry {Thread.sleep(1000);}…

ElasticSearch一对多关系方案

一、前言 使用MySQL做为存储&#xff0c;表与表之间有很多是一对多关系&#xff0c;比如订单和订单商品明细&#xff0c;客户和客户地址等等&#xff0c;但是因为ES本身是扁平化文档结构&#xff0c;一般不同索引之间是没有关系的&#xff0c;ES在处理这种关系时相比MySQL并不…

Python计算巴氏距离

Python计算巴氏距离 巴氏距离简介 在统计中&#xff0c;巴氏距离&#xff08;Bhattacharyya Distance&#xff09;测量两个离散或连续概率分布的相似性。它与衡量两个统计样品或种群之间的重叠量的巴氏系数密切相关。巴氏距离和巴氏系数以20世纪30年代曾在印度统计研究所工作…

分布式事务-TCC异常-幂等性

1、幂等性问题&#xff1a; 二阶段提交时&#xff0c;如果二阶段执行成功通知TC时出现网路或其他问题中断&#xff0c;那么TC没有收到执行成功的通知&#xff0c;TC内部有定时器不断的重试二阶段方法&#xff0c;导致接口出现幂等性问题。 2、解决方法 和空回滚问题一样也是…

Elastic SQL 输入:数据库指标可观测性的通用解决方案

作者&#xff1a;Lalit Satapathy, Ishleen Kaur, Muthukumar Paramasivam Elastic SQL 输入&#xff08;metricbeat 模块和输入包&#xff09;允许用户以灵活的方式对许多支持的数据库执行 SQL 查询&#xff0c;并将结果指标提取到 Elasticsearch。 本博客深入探讨了通用 SQL …

基于SpringBoot的课程答疑系统

目录 前言 一、技术栈 二、系统功能介绍 学生信息管理 科目类型管理 老师回答管理 我的收藏管理 学生问题 留言反馈 交流区 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#x…

SPSS探索性分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件可在个人主页—…

求解平面上物体的有向3d包围盒

算法流程&#xff1a; &#xff08;1&#xff09;点云下采样&#xff08;体素滤波&#xff09;&#xff1b; &#xff08;2&#xff09;ransac算法分割拟合地面平面&#xff1b; &#xff08;3&#xff09;裁剪工作区域&#xff08;指定空间中四个点&#xff0c;裁剪点云只保留…

C++_基础语法

一、关键字 常用语法 #include<iostream>using namespace std;// 全局常量 #define DAY 30void main() {/** 变量与输出*/// 局部常量const int year 2023;// 控制台输出cout << "hello world" << endl;cout << "天&#xff1a;"…

国庆加速度!新增功能点锁定功能,敏捷开发新增估算功能,助力项目快速突破!

大家好&#xff0c;CoCode开发云旗下Co-Project V3.6智能项目管理平台正式发布&#xff0c;平台新增功能点锁定功能、敏捷开发模式新增估算板块和两种估算方式。 功能点锁定功能进一步提高了项目估算的灵活性和准确性&#xff0c;有利于提高项目估算效率&#xff1b;而敏捷开发…

Unity2023打包首包从78Mb到3.0Mb-震惊-我做对了什么

&#xff08;全程并没有使用AssetBundle , 历史原因&#xff0c;Resources目录还有不少资源残留&#xff09; 曾经的我在2019打包过最小包10m左右&#xff0c;后来发现到了Unity2020之后暴增到40m&#xff0c;又加上2023版本URP&#xff0c;1个Unity输出包可能至少55M 如下图…

Ubuntu基于Docker快速配置GDAL的Python、C++环境

本文介绍在Linux的Ubuntu操作系统中&#xff0c;基于Docker快速配置Python、C等不同编程语言均可用的地理数据处理库GDAL的方法。 首先&#xff0c;我们访问GDAL库的Docker镜像官方网站&#xff08;https://github.com/OSGeo/gdal/tree/master/docker&#xff09;。其中&#x…

Abstract Factory 抽象工厂模式简介与 C# 示例【创建型】

〇、简介 1、什么是抽象工厂模式&#xff1f; 一句话解释&#xff1a; 提供一个接口&#xff0c;以创建一系列相关或相互依赖的抽象对象&#xff0c;而无需指定它们具体的类。&#xff08;将一系列抽象类装进接口&#xff0c;一次接口实现&#xff0c;就必须实例化这一系列抽象…

如何在Ubuntu中切换root用户和普通用户

问题 大家在新装Ubuntu之后&#xff0c;有没有发现自己进入不了root用户&#xff0c;su root后输入密码根本进入不了&#xff0c;这怎么回事呢&#xff1f; 打开Ubuntu命令终端&#xff1b; 输入命令&#xff1a;su root&#xff1b; 回车提示输入密码&#xff1b; 提示&…

[ubuntu]ubuntu设置虚拟内存

首先查看自己是否加过虚拟内存或者查看虚拟内存当前状态可以命令&#xff1a; free -mh 创建交换分区&#xff1a; sudo mkdir /swap cd /swap sudo dd if/dev/zero ofswapfile bs1024 count12582912 其中count是自己分配内存大小&#xff0c;上面为12GB&#xff0c;你可…

视频异常检测:Human Kinematics-inspired Skeleton-based Video Anomaly Detection

论文作者&#xff1a;Jian Xiao,Tianyuan Liu,Genlin Ji 作者单位&#xff1a;Nanjing Normal University;The Hong Kong Polytechnic University 论文链接&#xff1a;http://arxiv.org/abs/2309.15662v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;视频异常检测…