【C#】C#在不同的类中如何进行通信的示例【ds:包含:类传入直接调用方法,delegate委托和事件 ,属性,interface接口,依赖注入,static静态】

static:

C#在不同的类中如何进行通信的实例:

方法1:【方法调用】

一个方法中直接调用另一个类中的方法

namespace ClassABConsoleApp
{
    public class ClassA
    {
        public void DoSomething()
        {
            Console.WriteLine("ClassA is doing something.");
        }
    }
}
namespace ClassABConsoleApp
{
    //ClassB调用ClassA的办法
    public class ClassB
    {
        private ClassA _classA;     //在classB中调用classA

        public ClassB(ClassA classA)
        {
            _classA = classA;
        }

        public void Execute()
        {
            _classA.DoSomething();
        }

    }
}

使用:

// 使用
ClassA a = new ClassA();
ClassB b = new ClassB(a);
b.Execute();

Console.WriteLine("End!");

方法2:【事件和委托】

一个类可以通过事件通知另一个类。

//事件和委托来传递信息
public class Publisher
{
    public delegate void NotifyHandler(string message);     //委托
    public event NotifyHandler Notify;                      //事件【基于委托】

    public void DoSomething()
    {
        Console.WriteLine("Publisher is doing something.");
        Notify?.Invoke("Task completed.");      //空条件运算符(Null-Conditional Operator)与事件调用结合的语法:如果Notify不为空,则Invoke()
                                                //安全的调用事件的方式,避免了 null 检查的繁琐代码,同时防止了空引用异常的发生。
    }
}
//事件和委托来传递信息
public class Subscriber
{
    public void OnNotify(string message)
    {
        Console.WriteLine($"Subscriber received: {message}");
    }
}
//使用方法2:【事件和委托】
// 一个类可以通过事件通知另一个类。
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();

publisher.Notify += subscriber.OnNotify;        //将OnNotify函数赋值给Notify事件
publisher.DoSomething();


方法2延申:委托与事件的详细介绍与示例:

通过委托与事件,C# 提供了一种灵活的方式来实现事件驱动编程

  • 委托:用于封装方法,可以作为参数传递或调用。【delegate 】
//定义委托
public delegate void MyDelegate(string message);

//使用委托:创建委托实例
public class Program
{
    public static void Main(string[] args)
    {
        // 创建委托实例并关联方法
        MyDelegate del = new MyDelegate(ShowMessage);

        // 调用委托
        del("Hello, World!");
    }

    public static void ShowMessage(string message)
    {
        Console.WriteLine(message);
    }
}

  • 事件:基于委托,用于在特定动作发生时通知其他对象。【event】

事件是基于委托的,它允许类或对象在特定动作发生时通知其他对象。事件通常用于实现观察者模式。

//定义事件
public class EventPublisher
{
    // 定义事件
    public event MyDelegate MyEvent;

    public void RaiseEvent(string message)
    {
        // 触发事件
        MyEvent?.Invoke(message);
    }
}

//使用事件:订阅,触发
public class Program
{
    public static void Main(string[] args)
    {
        EventPublisher publisher = new EventPublisher();

        // 订阅事件
        publisher.MyEvent += ShowMessage;

        // 触发事件
        publisher.RaiseEvent("Event triggered!");
    }

    public static void ShowMessage(string message)
    {
        Console.WriteLine(message);
    }
}
  • 多播委托:允许一个委托关联多个方法。【不用event,使用委托】
    委托可以关联多个方法,称为多播委托。当调用委托时,所有关联的方法都会按顺序执行。
public class Program
{
    public static void Main(string[] args)
    {
        MyDelegate del1 = new MyDelegate(ShowMessage);
        MyDelegate del2 = new MyDelegate(ShowAnotherMessage);

        // 多播委托
        MyDelegate multiDel = del1 + del2;

        // 调用多播委托
        multiDel("Hello from multi-cast delegate!");
    }

    public static void ShowMessage(string message)
    {
        Console.WriteLine("ShowMessage: " + message);
    }

    public static void ShowAnotherMessage(string message)
    {
        Console.WriteLine("ShowAnotherMessage: " + message);
    }
}

事件与委托的区别

委托:可以直接调用,也可以作为参数传递。

事件:只能在声明它的类中触发,外部类只能订阅或取消订阅事件。

简单应用:

使用事件和委托实现简单的按钮点击事件

public class Button
{
    // 定义事件
    public event EventHandler Click;

    public void OnClick()
    {
        // 触发事件
        Click?.Invoke(this, EventArgs.Empty);
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Button button = new Button();

        // 订阅事件
        button.Click += Button_Click;

        // 模拟按钮点击
        button.OnClick();
    }

    private static void Button_Click(object sender, EventArgs e)
    {
        Console.WriteLine("Button clicked!");
    }
}

方法3:【属性】

一个类可以通过属性访问,修改另一个类的状态。

//通过属性访问修改类间数据
public class ClassA_3
{
    public int Value { get; set; }
}
 public class ClassB_3
 {
     private ClassA_3 _classA_3;

     public ClassB_3(ClassA_3 classA_3)
     {
         _classA_3 = classA_3;
     }

     public void ModifyValue(int newValue)
     {
         _classA_3.Value = newValue;
         Console.WriteLine($"ClassA's value is now: {_classA_3.Value}");
     }
 }
//使用方法3:【属性】一个类可以通过属性访问,修改另一个类的状态。
// 使用
ClassA_3 a_3 = new ClassA_3();
ClassB_3 b_3 = new ClassB_3(a_3);
b_3.ModifyValue(42);

方法4:【接口】

通过接口定义契约,不同的类可以实现相同的接口并进行通信

//使用接口完成类间通信
public interface Interface1
{
    void SendMessage(string message);
}
//使用接口的ClassA
public class ClassA_Itf : Interface1
{
    //实现接口
    public void SendMessage(string message)
    {
        Console.WriteLine($"ClassA sends: {message}");
    }
}
//使用接口的ClassB
public class ClassB_Itf 
{
    public Interface1 _Interface1;  //自定义的用于传递数据的接口

    public ClassB_Itf(Interface1 Interface1)
    {
        _Interface1 = Interface1;
    }

    public void Execute()
    {
        _Interface1.SendMessage("Hello from ClassB");
    }
}

使用:

//使用方法4:接口
// 使用,新定义一个接口,classA实现接口函数,classB构造时传递入接口【classA】,从而使用classA的接口函数
ClassA_Itf a_Itf = new ClassA_Itf();
ClassB_Itf b_Itf = new ClassB_Itf(a_Itf);
b_Itf.Execute();

方法5:【依赖注入】

通过依赖注入框架(如ASP.NET Core中的内置DI容器)来管理类之间的依赖关系。【前部分跟接口相同】

//用于使用依赖注入,在类间通信
//新创建接口
public interface Interface_DI
{
    void PerformAction();
}
//用于依赖注入方法
public class ServiceClass_DI : Interface_DI
{
    //实现Interface_DI接口
    public void PerformAction()
    {
        Console.WriteLine("ServiceClass_DI is performing an action.");
    }
}

注入,注入有很多种办法,这里使用构造函数注入

public class ClientClass_DI
{
    private readonly Interface_DI _interface_DI;

    public ClientClass_DI(Interface_DI interface_DI)
    {
        _interface_DI = interface_DI;
    }

    public void Execute()
    {
        _interface_DI.PerformAction();
    }
}

使用:【依赖注入是一种设计模式,有几种方式进行注入:包括构造函数注入,属性注入,使用方法注入,使用依赖注入容器-ServiceCollection】

//使用方法5:依赖注入
//通过依赖注入框架(如ASP.NET Core中的内置DI容器)来管理类之间的依赖关系。
//1. 创建服务集合
var services = new ServiceCollection();         //需要安装安装包Microsoft.Extensions.DependencyInjection识别ServiceCollection
//2. 注册服务
services.AddSingleton<Interface_DI,ServiceClass_DI>(); //Singleton:在整个应用程序生命周期内,只会创建一个实例。
services.AddTransient<ClientClass_DI>();        //Transient:每次请求都会创建一个新的实例。
//3. 构建服务提供者
var serviceProvider = services.BuildServiceProvider();
//4. 解析服务
var client = serviceProvider.GetService<ClientClass_DI>();
client.Execute();

方法6:【静态类和静态方法】

public static class StaticTestClass
{
    public static void TestStaticMeg()
    {
        Console.WriteLine("StaticTestClass:TestStaticMes!");
    }
}
public  class TestClass_static
{
    public void DoSomething()
    {
        //静态类,静态方法可以直接调用
        StaticTestClass.TestStaticMeg();
    }
}
TestClass_static testClass= new TestClass_static();
testClass.DoSomething();

方法6延申:static关键字用法:-------------------------------------------------------------------------------------------------
static关键字定义静态成员,代表不是属于类的实例而是属于类本身,所有实例共享一个静态成员
静态字段(变量):属于类而不是属于类的实例,所有实例共享一个静态字段
静态方法:可以直接用类名调用静态方法而不需要创建类的实例
静态构造函数:

//静态构造函数用于初始化静态字段或执行只需要执行一次的静态初始化操作。静态构造函数在类第一次被使用之前自动调用,且只调用一次。
public class Logger
{
    public static string LogFile;

    static Logger()
    {
        LogFile = "log.txt";
        Console.WriteLine("静态构造函数被调用");
    }
}
 Console.WriteLine(Logger.LogFile); // 输出: log.txt

静态类:静态类是不能被实例化的类,通常包含一组相关的静态成员,静态类中的所有成员都必须是静态的
静态属性:静态属性是属于类的属性,而不是类的实例。可以通过类名直接访问静态属性。

public class Settings
{
    private static string _appName;

    public static string AppName
    {
        get { return _appName; }
        set { _appName = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Settings.AppName = "MyApp";
        Console.WriteLine(Settings.AppName); // 输出: MyApp
    }
}

静态事件:属于类的事件,而不是类的实例,可以通过类名直接订阅或触发静态事件

public class Alarm
{
    public static event Action OnAlarmRaised;

    public static void RaiseAlarm()
    {
        OnAlarmRaised?.Invoke();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Alarm.OnAlarmRaised += () => Console.WriteLine("警报已触发!");
        Alarm.RaiseAlarm(); // 输出: 警报已触发!
    }
}

静态索引器:静态索引器允许通过索引访问静态集合或数组。

public class StaticCollection
{
    private static string[] _data = new string[10];

    public static string this[int index]
    {
        get { return _data[index]; }
        set { _data[index] = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        StaticCollection[0] = "Hello";
        StaticCollection[1] = "World";
        Console.WriteLine(StaticCollection[0]); // 输出: Hello
        Console.WriteLine(StaticCollection[1]); // 输出: World
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值