AI面试官:委托和事件

AI面试官:委托和事件

文章目录


当面试涉及委托和事件相关的问题时,通常会考察候选人对这两个重要概念的理解以及在实际场景中的应用能力。以下是一些常见的面试问题以及对应的答案,包括通俗易懂的实际案例和代码示例。如果大家还有什么想问的,我可以后续收集为大家出文章解答。

问题1:什么是委托(Delegate)?请用通俗易懂的方式解释委托的含义和用途。

答案: 委托是一种用于封装方法的类型,它可以将方法作为参数传递给其他方法或保存对方法的引用。委托可以用来实现回调机制和事件处理等场景,使得方法的调用可以更加灵活和动态。

实际案例: 假设我们有一个数字列表,我们希望对其中的每个数字进行平方运算,并将结果输出到控制台。我们可以使用委托来实现这个功能。

// 定义一个委托类型,它可以接受一个整数参数并返回一个整数结果
delegate int MathOperation(int number);

class Program
{
    
    
    static void Main()
    {
    
    
        List<int> numbers = new List<int> {
    
     1, 2, 3, 4, 5 };

        // 定义一个平方运算的方法
        int Square(int x) => x * x;

        // 使用委托将平方运算的方法应用到每个数字,并输出结果
        MathOperation squareOperation = Square;
        foreach (int num in numbers)
        {
    
    
            int result = squareOperation(num);
            Console.WriteLine($"平方运算后的结果:{
      
      result}");
        }
    }
}

问题2:什么是事件(Event)?请用通俗易懂的方式解释事件的含义和用途。

**答案:**事件是一种特殊类型的委托,用于实现观察者模式。事件允许对象在发生特定动作时通知其他对象,从而实现解耦和灵活的消息传递。

**实际案例:**假设我们有一个温度传感器,它可以检测环境温度,并在温度发生变化时触发一个事件通知。其他对象可以订阅这个事件,以便在温度变化时执行相应的逻辑。

// 定义一个温度传感器类
class TemperatureSensor
{
    
    
    // 定义一个委托类型用于表示温度变化的事件处理方法
    public delegate void TemperatureChangedEventHandler(object sender, double newTemperature);

    // 声明一个事件,用于在温度变化时通知其他对象
    public event TemperatureChangedEventHandler TemperatureChanged;

    private double temperature;

    // 模拟温度变化,并触发事件通知
    public void SimulateTemperatureChange(double newTemperature)
    {
    
    
        temperature = newTemperature;
        // 触发事件通知
        OnTemperatureChanged(newTemperature);
    }

    // 触发事件的方法
    protected virtual void OnTemperatureChanged(double newTemperature)
    {
    
    
        // 判断是否有订阅者,如果有则触发事件
        TemperatureChanged?.Invoke(this, newTemperature);
    }
}

class Program
{
    
    
    static void Main()
    {
    
    
        TemperatureSensor sensor = new TemperatureSensor();

        // 订阅温度变化事件,当温度变化时执行相应的逻辑
        sensor.TemperatureChanged += (sender, newTemperature) =>
        {
    
    
            Console.WriteLine($"温度变化,新温度:{
      
      newTemperature}");
        };

        // 模拟温度变化
        sensor.SimulateTemperatureChange(25.5);
        sensor.SimulateTemperatureChange(30.0);
    }
}

问题3:委托与事件有什么区别?它们在什么情况下使用?在什么情况下应该使用事件而不是委托?

**答案:**委托是一种用于封装方法的类型,它可以用于传递方法引用和实现回调机制。而事件是一种特殊类型的委托,它允许对象在特定动作发生时通知其他对象。主要区别在于委托是用于方法调用的,而事件是用于实现观察者模式的一种机制。

委托适用于需要将方法作为参数传递或保存方法引用的场景,例如在委托中封装不同的算法实现,然后将委托传递给其他方法进行调用。而事件适用于当一个对象的状态或动作发生变化时,需要通知其他对象做出响应的场景,例如用户点击按钮后触发的事件,其他对象可以订阅该事件来响应用户的操作。

应该使用事件而不是委托的情况是当我们希望在类的外部订阅和触发某个特定事件时。事件提供了更好的封装和抽象,使得类的内部实现细节对外部调用者隐藏,增强了类的封装性和安全性。

实际案例:考虑一个简单的温度传感器类,当温度变化时,希望通知外部订阅者。这时我们应该使用事件而不是委托。

csharpCopy codepublic delegate void TemperatureChangedEventHandler(double newTemperature);

public class TemperatureSensor
{
    
    
    // 使用事件来发布温度变化通知
    public event TemperatureChangedEventHandler TemperatureChanged;

    private double temperature;

    public double Temperature
    {
    
    
        get {
    
     return temperature; }
        set
        {
    
    
            if (temperature != value)
            {
    
    
                temperature = value;
                // 温度变化时触发事件
                OnTemperatureChanged(temperature);
            }
        }
    }

    protected virtual void OnTemperatureChanged(double newTemperature)
    {
    
    
        // 判断事件是否有订阅者
        if (TemperatureChanged != null)
        {
    
    
            // 触发事件
            TemperatureChanged(newTemperature);
        }
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        TemperatureSensor sensor = new TemperatureSensor();

        // 订阅事件
        sensor.TemperatureChanged += OnTemperatureChanged;

        // 模拟温度变化
        sensor.Temperature = 25.5;
    }

    static void OnTemperatureChanged(double newTemperature)
    {
    
    
        Console.WriteLine($"温度变化,新温度:{
      
      newTemperature}");
    }
}

在上面的示例中,TemperatureSensor 类使用了事件 TemperatureChanged 来发布温度变化通知。Program 类订阅了该事件,并在事件触发时调用 OnTemperatureChanged 方法。这样一来,TemperatureSensor 类的内部实现细节对外部调用者隐藏,通过事件的方式提供了更好的封装和抽象。

问题4:事件的订阅和取消订阅是如何实现的?

**答案:**事件的订阅和取消订阅是通过使用 += 和 -= 运算符来实现的。当一个对象订阅事件时,它将一个事件处理方法添加到事件的委托链中。而当对象取消订阅事件时,它将相应的事件处理方法从事件的委托链中移除。

**实际案例:**在上述温度传感器的例子中,订阅事件的代码使用 += 运算符:

sensor.TemperatureChanged += (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"温度变化,新温度:{
      
      newTemperature}");
};

如果要取消订阅事件,可以使用 -= 运算符:

// 取消订阅事件
sensor.TemperatureChanged -= (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"温度变化,新温度:{
      
      newTemperature}");
};

问题5:请解释 multicast 委托是什么,并说明它在事件中的作用?

**答案:**multicast 委托是一种特殊的委托,它包含了多个方法的引用。在事件中,事件的委托类型通常是 multicast 委托。当一个事件有多个订阅者时,事件的委托链中就会包含多个方法的引用,每个方法代表一个订阅者的事件处理方法。当事件触发时,所有在委托链中的方法都会被依次调用,从而通知所有的订阅者。

**实际案例:**在之前的温度传感器例子中,如果有多个对象订阅了 TemperatureChanged 事件,它们的事件处理方法都会添加到委托链中:

TemperatureSensor sensor = new TemperatureSensor();

// 订阅事件,添加多个事件处理方法到委托链中
sensor.TemperatureChanged += (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"订阅者1:温度变化,新温度:{
      
      newTemperature}");
};

sensor.TemperatureChanged += (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"订阅者2:温度变化,新温度:{
      
      newTemperature}");
};

当事件触发时,所有订阅者的事件处理方法都会被依次调用:

sensor.SimulateTemperatureChange(25.5);

输出:

订阅者1:温度变化,新温度:25.5
订阅者2:温度变化,新温度:25.5

这些问题和答案涵盖了委托和事件的基本概念、用法以及在实际场景中的应用。在面试中,重点强调您对委托和事件的理解,以及如何使用它们解决实际问题,将有助于展示您的技能和经验。

问题6:什么是异步委托(async delegate)?如何在异步编程中使用委托?

**答案:**异步委托是一种允许在异步编程中使用的委托类型。它用于封装一个异步操作,并可以在操作完成后返回结果或执行回调。在异步编程中,我们通常使用异步委托来调用异步方法,并使用 async 和 await 关键字来等待异步操作的完成。

**实际案例:**假设有一个异步方法,用于从远程服务器获取数据:

public async Task<string> GetDataAsync()
{
    
    
    // 模拟异步操作,等待1秒钟
    await Task.Delay(1000);
    return "Hello, async delegate!";
}

我们可以使用异步委托来调用这个异步方法,并在异步操作完成后获取结果:

public async Task Main()
{
    
    
    // 使用异步委托调用异步方法
    Func<Task<string>> getDataAsync = GetDataAsync;

    // 等待异步操作完成并获取结果
    string result = await getDataAsync();

    Console.WriteLine(result); // 输出:Hello, async delegate!
}

问题7:如何使用事件来实现观察者模式?

**答案:**观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。在 C# 中,我们可以使用事件来实现观察者模式。首先,定义一个事件,然后在观察者类中订阅这个事件,当事件触发时,观察者会收到通知并执行相应的操作。

**实际案例:**假设有一个发布者类 Publisher,负责产生数据并通知观察者:

// 定义事件委托
public delegate void DataChangedEventHandler(object sender, string newData);

public class Publisher
{
    
    
    // 定义事件
    public event DataChangedEventHandler DataChanged;

    public void GenerateData(string data)
    {
    
    
        // 产生数据并通知观察者
        OnDataChanged(data);
    }

    protected virtual void OnDataChanged(string newData)
    {
    
    
        DataChanged?.Invoke(this, newData);
    }
}

public class Observer
{
    
    
    public void Subscribe(Publisher publisher)
    {
    
    
        // 订阅事件
        publisher.DataChanged += DataChangedHandler;
    }

    private void DataChangedHandler(object sender, string newData)
    {
    
    
        // 处理数据变化
        Console.WriteLine($"收到新数据:{
      
      newData}");
    }
}

然后在应用程序中使用观察者模式:

public void Main()
{
    
    
    Publisher publisher = new Publisher();
    Observer observer = new Observer();

    // 观察者订阅事件
    observer.Subscribe(publisher);

    // 产生数据并通知观察者
    publisher.GenerateData("Hello, observer pattern!");
}

输出:

收到新数据:Hello, observer pattern!

问题8:什么是委托链(Delegate Chain)?它在什么情况下会出现?

**答案:**委托链是多个委托的组合,它将多个委托的方法引用链接在一起,形成一个调用链。在委托链中,多个委托的方法会按照添加的顺序被依次调用。委托链通常在事件的订阅和取消订阅过程中出现,当一个事件有多个订阅者时,事件的委托链中就会包含多个方法的引用,每个方法代表一个订阅者的事件处理方法。

**实际案例:**在问题5的温度传感器例子中,我们使用了委托链:

TemperatureSensor sensor = new TemperatureSensor();

// 订阅事件,添加多个事件处理方法到委托链中
sensor.TemperatureChanged += (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"订阅者1:温度变化,新温度:{
      
      newTemperature}");
};

sensor.TemperatureChanged += (sender, newTemperature) =>
{
    
    
    Console.WriteLine($"订阅者2:温度变化,新温度:{
      
      newTemperature}");
};

当事件触发时,委托链中的两个事件处理方法都会被依次调用,通知所有的订阅者。

问题9:什么是多播委托(Multicast Delegate)?请给一个多播委托的示例。

答案:多播委托是一种特殊类型的委托,它可以持有多个方法的引用,并且可以按顺序依次调用这些方法。在 C# 中,我们可以使用 += 运算符将多个方法添加到多播委托中,使用 -= 运算符将方法从多播委托中移除。

实际案例:假设有一个使用多播委托的示例,用于向不同的日志记录方法发布日志消息:

csharpCopy codepublic delegate void LoggerDelegate(string message);

public class Logger
{
    
    
    public event LoggerDelegate LogMessage;

    public void Log(string message)
    {
    
    
        // 触发多播委托,依次调用订阅的所有日志记录方法
        LogMessage?.Invoke(message);
    }
}

public class ConsoleLogger
{
    
    
    public void WriteToConsole(string message)
    {
    
    
        Console.WriteLine($"Console Logger: {
      
      message}");
    }
}

public class FileLogger
{
    
    
    public void WriteToFile(string message)
    {
    
    
        // 省略文件写入逻辑
        Console.WriteLine($"File Logger: {
      
      message}");
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        Logger logger = new Logger();
        ConsoleLogger consoleLogger = new ConsoleLogger();
        FileLogger fileLogger = new FileLogger();

        // 将两个方法添加到多播委托中
        logger.LogMessage += consoleLogger.WriteToConsole;
        logger.LogMessage += fileLogger.WriteToFile;

        // 发布日志消息
        logger.Log("Hello, Multicast Delegate!");

        // 移除一个方法
        logger.LogMessage -= consoleLogger.WriteToConsole;

        // 再次发布日志消息
        logger.Log("Hello again, Multicast Delegate!");
    }
}

输出:

arduinoCopy codeConsole Logger: Hello, Multicast Delegate!
File Logger: Hello, Multicast Delegate!
File Logger: Hello again, Multicast Delegate!

在上面的示例中,Logger 类定义了一个多播委托 LoggerDelegate,并且有一个 LogMessage 事件用于持有多播委托。ConsoleLogger 和 FileLogger 类分别定义了用于写入日志消息的方法。在 Program 类中,我们将两个方法添加到 Logger 的多播委托中,并触发了日志消息的发布。

问题10:委托和事件有哪些使用注意事项?请分别说明。

答案:

  • 委托注意事项:
    1. 委托是可变的:委托对象可以添加或移除多个方法。在使用委托时,需要注意委托的调用顺序,以及确保不会因为意外的委托调用导致不可预测的结果。
    2. 委托空引用检查:在调用委托之前,应该检查委托是否为空,以避免 NullReferenceException 异常。
    3. 委托生命周期:需要注意委托对象的生命周期,确保不会在不需要时仍然持有对委托的引用,避免引起内存泄漏。
  • 事件注意事项:
    1. 事件是封装的:事件提供了更好的封装性,订阅者只能添加或移除事件,不能直接调用事件。在定义事件时,应该遵循事件的标准模式,即使用 event 关键字定义,防止误操作。
    2. 事件线程安全:事件的调用是在触发事件的类的线程上执行的。如果事件处理方法中有耗时操作或对 UI 的更新,需要确保事件处理是线程安全的。
    3. 事件触发顺序:事件的订阅者的调用顺序与订阅顺序相同。如果需要控制事件订阅者的执行顺序,可以使用多播委托。

问题11:事件在什么情况下会导致内存泄漏?如何避免事件引起的内存泄漏?

答案:事件会导致内存泄漏的情况是当订阅事件的对象没有正确地移除对事件的订阅时,即事件发布者对事件订阅者持有了长时间的引用,导致订阅者无法被垃圾回收。这可能发生在以下情况:

  • 订阅者没有在适当的时候取消事件订阅。
  • 订阅者的生命周期比事件发布者长,导致事件发布者持有对订阅者的引用。
  • 订阅者使用匿名方法或 lambda 表达式订阅事件,这些订阅可能很难被取消。

为避免事件引起的内存泄漏,可以采取以下措施:

  • 在订阅事件的对象销毁时,手动取消对事件的订阅。
  • 使用弱引用(WeakReference)来订阅事件,这样即使订阅者被垃圾回收,事件发布者仍然能够正确地触发事件,并避免内存泄漏。
  • 在事件发布者的类中,提供一个显式的取消订阅方法,允许订阅者主动取消事件订阅。

下面是一个示例,展示如何使用弱引用来订阅事件,避免内存泄漏:

csharpCopy codepublic class EventPublisher
{
    
    
    // 使用弱引用来订阅事件
    private List<WeakReference<EventListener>> listeners = new List<WeakReference<EventListener>>();

    public event EventHandler EventOccurred;

    public void Subscribe(EventListener listener)
    {
    
    
        // 使用弱引用包装订阅者,避免强引用
        listeners.Add(new WeakReference<EventListener>(listener));
    }

    public void Unsubscribe(EventListener listener)
    {
    
    
        // 取消订阅时,从列表中移除对订阅者的弱引用
        listeners.RemoveAll(r => !r.TryGetTarget(out var target) || target == listener);
    }

    public void PublishEvent()
    {
    
    
        EventOccurred?.Invoke(this, EventArgs.Empty);
    }
}

public class EventListener
{
    
    
    public EventListener(EventPublisher publisher)
    {
    
    
        publisher.Subscribe(this);
    }

    public void HandleEvent(object sender, EventArgs e)
    {
    
    
        Console.WriteLine("Event occurred!");
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        EventPublisher publisher = new EventPublisher();
        EventListener listener = new EventListener(publisher);

        // 发布事件
        publisher.PublishEvent();

        // 取消订阅事件
        publisher.Unsubscribe(listener);

        // 发布事件,由于订阅者已经取消订阅,不会再处理事件
        publisher.PublishEvent();
    }
}

在上面的示例中,EventPublisher 类使用弱引用来订阅事件,确保即使订阅者被垃圾回收,事件发布者仍然能够正确地触发事件,并避免内存泄漏。

问题12:请解释委托的使用场景和优势。

答案:委托是一种类型安全的函数指针,用于引用方法并允许将方法作为参数传递给其他方法。委托的主要使用场景和优势包括:

  • 回调机制:委托允许在事件发生时调用预定义的方法,实现事件与处理逻辑的分离,从而实现回调机制。
  • 多播委托:可以将多个方法绑定到一个委托,然后在调用委托时依次触发这些方法,简化多个方法的调用。
  • 解耦合:委托使得不同模块之间可以松耦合,使代码更加灵活、可扩展,并增强了代码的可读性和维护性。
  • 线程异步编程:委托结合线程可实现异步编程,将耗时的操作交给后台线程处理,避免阻塞主线程,提高应用程序的响应性。
  • 泛型委托:C# 中引入的 Func 和 Action 等泛型委托可以接收不同数量和类型的参数,更加方便地定义和使用委托。

问题13:请解释事件的使用场景和优势。

答案:事件是一种特殊类型的委托,用于实现发布者/订阅者模式,主要用于在对象之间通信和处理异步事件。事件的主要使用场景和优势包括:

  • 发布者/订阅者模式:事件允许一个对象(发布者)发布事件,而其他对象(订阅者)可以订阅事件并在事件发生时做出响应,实现了发布者和订阅者之间的松耦合。
  • UI 交互:在图形用户界面中,事件可用于处理按钮点击、文本框输入等用户交互事件,将用户操作与逻辑处理分离,使代码更易于维护。
  • 异步编程:事件适用于实现异步编程模型,例如在异步网络通信、文件读写等场景中,通过事件通知异步操作的完成。
  • 插件机制:事件可用于实现插件式架构,允许其他模块注册事件处理程序并扩展应用程序的功能。
  • 系统监控:事件可用于实现系统监控和日志记录,将系统状态变化和异常情况通知订阅者,以便及时采取措施。

问题14:什么是委托链(Multicast Delegate)?如何使用委托链?

答案:委托链是将多个委托实例组合成一个委托实例的机制。C# 中的委托是单播委托,但通过使用 + 运算符,可以将多个委托合并为委托链。委托链的使用方式如下:

csharpCopy codepublic delegate void MyDelegate(string message);

public class Program
{
    
    
    public static void Main()
    {
    
    
        MyDelegate delegate1 = Method1;
        MyDelegate delegate2 = Method2;

        // 将两个委托合并为委托链
        MyDelegate delegateChain = delegate1 + delegate2;

        // 依次调用委托链中的方法
        delegateChain("Hello, World!");
    }

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

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

运行上面的代码,输出结果为:

makefileCopy codeMethod1: Hello, World!
Method2: Hello, World!

通过合并委托为委托链,可以同时调用多个方法,方便实现多个方法的调用和执行。需要注意的是,委托链的执行顺序与合并委托的顺序相同。

问题15:什么是异步委托(Async Delegate)?如何使用异步委托实现异步编程?

答案:异步委托是通过委托和异步操作结合使用,实现异步编程的一种方式。C# 5.0 引入了 async/await 关键字来简化异步编程,可以将异步方法封装成异步委托。

使用异步委托实现异步编程的步骤如下:

  1. 定义一个异步方法,方法签名前加上 async 关键字,并使用 TaskTask<T> 作为返回类型,表示异步操作的结果。
  2. 在异步方法内部,使用 await 关键字来等待异步操作的完成,并获取异步操作的结果。
  3. 在需要异步执行的地方,创建异步委托实例,并将异步方法作为委托的参数传入。
  4. 通过异步委托的 BeginInvoke 方法异步调用委托。

以下是一个使用异步委托实现异步编程的示例:

csharpCopy codepublic delegate string AsyncMethodDelegate();

public class Program
{
    
    
    public static async Task<string> LongRunningAsyncMethod()
    {
    
    
        await Task.Delay(2000); // 模拟耗时操作
        return "Task completed.";
    }

    public static void Main()
    {
    
    
        AsyncMethodDelegate asyncDelegate = LongRunningAsyncMethod;

        // 使用异步委托的 BeginInvoke 方法异步调用委托
        IAsyncResult asyncResult = asyncDelegate.BeginInvoke(null, null);

        // 执行其他操作,不会阻塞主线程
        Console.WriteLine("Doing something else...");

        // 使用异步委托的 EndInvoke 方法获取异步操作的结果
        string result = asyncDelegate.EndInvoke(asyncResult);

        Console.WriteLine(result);
    }
}

运行上面的代码,会先输出 “Doing something else…”,然后约2秒后输出 “Task completed.”。这表明在调用异步委托时,主线程可以继续执行其他操作而不会被阻塞,异步方法会在后台线程上执行。

问题16:C# 中的事件处理程序如何取消事件的继续传播?

答案:在事件处理程序中,可以使用 e.Handled = true; 语句来取消事件的继续传播。当事件处理程序设置了 e.Handledtrue 后,事件将不再传播给其他订阅者,即停止触发其他事件处理程序。

问题17:委托和事件在事件处理中的具体应用场景是什么?

答案:委托和事件在事件处理中有以下具体应用场景:

  1. 用户界面交互:委托和事件可用于处理用户界面交互,如按钮点击、文本框输入等。当用户执行某些操作时,触发相应的事件,并调用事件处理程序来处理用户的输入。
  2. 异步编程:事件可以与异步编程结合使用,允许耗时的操作在后台线程中执行,以提高应用程序的响应性。委托可以用于定义异步方法,并在异步操作完成后触发事件通知结果。
  3. 系统监控和日志:事件可以用于实现系统监控和日志记录。当系统状态发生变化或发生异常情况时,发布相应的事件通知订阅者,以便及时采取措施。
  4. 发布者/订阅者模式:事件适用于实现发布者/订阅者模式,允许一个对象发布事件,而其他对象可以订阅事件并在事件发生时做出响应。这种模式使对象之间实现解耦,从而提高代码的灵活性和可维护性。
  5. 多播委托:事件处理中的委托链可用于实现多播委托,将多个方法绑定在一起形成委托链。当事件发生时,通过调用委托链一次性触发所有绑定的方法。
  6. 插件机制:事件可以用于实现插件式架构,允许其他模块注册事件处理程序并扩展应用程序的功能。这种模式允许应用程序在运行时动态加载和卸载插件,实现灵活的扩展性。
  7. 事件冒泡:在一些 UI 框架中,事件可以冒泡到父级控件,从而使整个控件树能够处理该事件。这样,事件处理可以在更高层次进行统一管理和处理。

问题18:什么是匿名方法和 lambda 表达式?它们有什么区别?

答案:匿名方法是一种没有方法名的方法,通常用于将方法作为参数传递给其他方法。匿名方法使用 delegate 关键字定义,并可用于替代委托的具名方法。匿名方法的语法类似于常规方法,但没有方法名,如:

csharpCopy codedelegate void MyDelegate(int x);

MyDelegate myDelegate = delegate (int x) {
    
     Console.WriteLine(x); };

Lambda 表达式是一种匿名函数,用于创建简洁的方法体并将其传递给委托或作为参数传递给其他方法。Lambda 表达式使用 => 运算符来定义,并可以省略参数类型(根据上下文推断)和大括号(对于单行表达式)。Lambda 表达式的语法如下:

csharpCopy code
MyDelegate myDelegate = x => Console.WriteLine(x);

区别:

  1. 语法:匿名方法使用 delegate 关键字定义,而 lambda 表达式使用 => 运算符定义。
  2. 参数类型:匿名方法中的参数类型必须显式指定,而 lambda 表达式可以根据上下文自动推断参数类型。
  3. 代码简洁性:lambda 表达式通常更简洁,尤其是对于单行代码,可以省略大括号和 return 语句。

这些问题和答案可以帮助您理解委托和事件的基本概念以及在实际场景中的应用。在面试中,展示您对委托和事件的理解,并结合实际案例和代码,可以更好地突显您的技能和经验。

本文由mdnice多平台发布

猜你喜欢

转载自blog.csdn.net/qq_36799389/article/details/131879270