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"));
    }
}
相关推荐
低代码布道师6 分钟前
第五部分:第一节 - Node.js 简介与环境:让 JavaScript 走进厨房
开发语言·javascript·node.js
盛夏绽放22 分钟前
Python字符串常用方法详解
开发语言·python·c#
好吃的肘子2 小时前
Elasticsearch架构原理
开发语言·算法·elasticsearch·架构·jenkins
nlog3n2 小时前
Go语言交替打印问题及多种实现方法
开发语言·算法·golang
kaixin_learn_qt_ing2 小时前
Golang
开发语言·后端·golang
ddd...e_bug2 小时前
Shell和Bash介绍
开发语言·bash
C4程序员3 小时前
Java百度身份证识别接口实现【配置即用】
java·开发语言
unityのkiven3 小时前
C++中的虚表和虚表指针的原理和示例
开发语言·c++
炒空心菜菜3 小时前
MapReduce 实现 WordCount
java·开发语言·ide·后端·spark·eclipse·mapreduce
(・Д・)ノ3 小时前
python打卡day27
开发语言·python