C# 使用泛型协变性

在 C# 中处理多个类型的生产者时,可以使用泛型接口结合协变性。以下是一个示例,展示如何实现一个支持多个类型的生产者。

协变性

csharp 复制代码
using System;
using System.Collections.Generic;

public interface IProducer<out T>
{
    T Produce();
}

public class FruitProducer : IProducer<Fruit>
{
    public Fruit Produce()
    {
        return new Fruit("Apple");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public Apple Produce()
    {
        return new Apple("Granny Smith");
    }
}

public class OrangeProducer : IProducer<Orange>
{
    public Orange Produce()
    {
        return new Orange("Navel Orange");
    }
}

public class Fruit
{
    public string Name { get; }
    
    public Fruit(string name)
    {
        Name = name;
    }
}

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

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

class Program
{
    static void Main()
    {
        List<IProducer<Fruit>> producers = new List<IProducer<Fruit>>()
        {
            new FruitProducer(),
            new AppleProducer(),
            new OrangeProducer()
        };

        foreach (var producer in producers)
        {
            ProduceFruit(producer);
        }
    }

    static void ProduceFruit(IProducer<Fruit> producer)
    {
        Fruit fruit = producer.Produce();
        Console.WriteLine($"Produced: {fruit.Name}");
    }
}

非协变性

csharp 复制代码
using System;

// 定义非协变的泛型接口
public interface IProducer<T>
{
    T Produce();
}

// 实现生产者类
public class FruitProducer : IProducer<Fruit>
{
    public Fruit Produce()
    {
        return new Fruit("Apple");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public Apple Produce()
    {
        return new Apple("Granny Smith");
    }
}

// 基类和子类
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 = fruitProducer.Produce();
        Apple apple = appleProducer.Produce();

        // 输出结果
        Console.WriteLine($"Produced: {fruit.Name}");
        Console.WriteLine($"Produced: {apple.Name}");
    }
}

协变性+委托

csharp 复制代码
using System;

// 定义协变的泛型委托
public delegate T ProducerDelegate<out T>();

// 定义协变的泛型接口
public interface IProducer<out T>
{
    T Produce();
}

// 实现生产者类
public class FruitProducer : IProducer<Fruit>
{
    public Fruit Produce()
    {
        return new Fruit("Apple");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public Apple Produce()
    {
        return new Apple("Granny Smith");
    }
}

// 基类和子类
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 = fruitDelegate();
        Apple apple = appleDelegate();

        // 输出结果
        Console.WriteLine($"Produced: {fruit.Name}");
        Console.WriteLine($"Produced: {apple.Name}");
    }
}

非协变性+委托

csharp 复制代码
using System;

// 定义非协变的泛型委托
public delegate T ProducerDelegate<T>();

// 定义非协变的泛型接口
public interface IProducer<T>
{
    T Produce();
}

// 实现生产者类
public class FruitProducer : IProducer<Fruit>
{
    public Fruit Produce()
    {
        return new Fruit("Apple");
    }
}

public class AppleProducer : IProducer<Apple>
{
    public Apple Produce()
    {
        return new Apple("Granny Smith");
    }
}

// 基类和子类
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 = fruitDelegate();
        Apple apple = appleDelegate();

        // 输出结果
        Console.WriteLine($"Produced: {fruit.Name}");
        Console.WriteLine($"Produced: {apple.Name}");
    }
}
相关推荐
忒可君1 小时前
C# winform FTP功能
开发语言·windows·c#
时光追逐者2 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 50 期(2025年8.11-8.17)
c#·.net·.netcore·.net core
一个会的不多的人3 小时前
C# NX二次开发:操作按钮控件Button和标签控件Label详解
开发语言·c#
咕白m6253 小时前
C# 实现 PDF 转图片 - 分辨率设置、图片格式选择
后端·c#
与火星的孩子对话6 小时前
Unity高级开发:反射原理深入解析与实践指南 C#
java·unity·c#·游戏引擎·lucene·反射
Dm_dotnet6 小时前
回顾一下WPF原生实现命令
c#
程序设计实验室6 小时前
纯 C#实现+AOT 打造的智能PDF目录提取工具 PdfTocExtractor
c#·aot
BD_Marathon9 小时前
消费者API
c#·linq
CallZhang2101 天前
Vision Master的C#脚本与opencv联合编程
opencv·计算机视觉·c#·视觉检测
AI视觉网奇1 天前
kafka 冲突解决 kafka安装
c#·linq