C# 使用泛型逆变性

在 C# 中,使用 in 关键字可以指定逆变性。以下是一个示例,展示如何使用逆变性和泛型接口来处理多个类型的生产者。

逆变性

csharp 复制代码
using System;

// 定义逆变的泛型接口
public interface IProducer<in T>
{
    void Produce(T item);
}

// 实现生产者类
public class FruitProducer : IProducer<Fruit>
{
    public void Produce(Fruit fruit)
    {
        Console.WriteLine($"Produced a fruit: {fruit.Name}");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public void Produce(Apple apple)
    {
        Console.WriteLine($"Produced an apple: {apple.Name}");
    }
}

// 基类和子类
public class Fruit
{
    public string Name { get; }
    
    public Fruit(string name)
    {
        Name = name;
    }
}

public class Apple : Fruit
{
    public Apple(string name) : base(name) { }
}

// 主程序
class Program
{
    static void Main()
    {
        // 创建生产者实例
        IProducer<Fruit> fruitProducer = new FruitProducer();
        IProducer<Apple> appleProducer = new AppleProducer();

        // 创建水果和苹果
        Fruit fruit = new Fruit("Banana");
        Apple apple = new Apple("Granny Smith");

        // 使用生产者
        fruitProducer.Produce(fruit);
        appleProducer.Produce(apple);

        // 使用逆变
        IProducer<Fruit> fruitProducerFromApple = appleProducer;
        fruitProducerFromApple.Produce(new Apple("Honeycrisp"));
    }
}

逆变性+委托

csharp 复制代码
using System;

// 定义逆变的泛型委托
public delegate void ProducerDelegate<in T>(T item);

// 定义逆变的泛型接口
public interface IProducer<in T>
{
    void Produce(T item);
}

// 实现生产者类
public class FruitProducer : IProducer<Fruit>
{
    public void Produce(Fruit fruit)
    {
        Console.WriteLine($"Produced a fruit: {fruit.Name}");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public void Produce(Apple apple)
    {
        Console.WriteLine($"Produced an apple: {apple.Name}");
    }
}

// 基类和子类
public class Fruit
{
    public string Name { get; }
    
    public Fruit(string name)
    {
        Name = name;
    }
}

public class Apple : Fruit
{
    public Apple(string name) : base(name) { }
}

// 主程序
class Program
{
    static void Main()
    {
        // 创建生产者实例
        IProducer<Fruit> fruitProducer = new FruitProducer();
        IProducer<Apple> appleProducer = new AppleProducer();

        // 创建委托实例
        ProducerDelegate<Fruit> fruitDelegate = fruitProducer.Produce;
        ProducerDelegate<Apple> appleDelegate = appleProducer.Produce;

        // 创建水果和苹果
        Fruit fruit = new Fruit("Banana");
        Apple apple = new Apple("Granny Smith");

        // 使用委托生产水果和苹果
        fruitDelegate(fruit);
        appleDelegate(apple);

        // 使用逆变
        ProducerDelegate<Fruit> fruitDelegateFromApple = appleProducer.Produce;
        fruitDelegateFromApple(new Apple("Honeycrisp"));
    }
}
相关推荐
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
神仙别闹2 天前
基于C#+MySQL实现(WinForm)个人聊天室软件
c#
伞伞悦读2 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车2 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁2 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
kybs19912 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
孙启超2 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int2 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
CoderYanger2 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读2 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json