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"));
    }
}
相关推荐
不正经学生4 小时前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
门思科技4 小时前
LoRaWAN 设备类别:Class A、B、C 对比与选型指南
c语言·开发语言·php
恋恋西风7 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
Brilliantwxx7 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
BizzZ_7 小时前
C++(22)——类型转换和IO流
开发语言·c++
小范同学_7 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
geovindu8 小时前
CSharp: 万年历
开发语言·后端·c#·.net
我找到地球的支点啦8 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
予昊8 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
weixin_461408589 小时前
Mybatis-flex小记
java·开发语言·mybatis