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}");
    }
}
相关推荐
“抚琴”的人5 小时前
【机械视觉】C#+VisionPro联合编程———【六、visionPro连接工业相机设备】
c#·工业相机·visionpro·机械视觉
FAREWELL000757 小时前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
CodeCraft Studio7 小时前
Excel处理控件Spire.XLS系列教程:C# 合并、或取消合并 Excel 单元格
前端·c#·excel
勘察加熊人9 小时前
forms实现连连看
c#
hvinsion9 小时前
PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具
c#·powerpoint·ppt·ppt助手·ppt翻页
weixin_3077791310 小时前
使用C#实现从Hive的CREATE TABLE语句中提取分区字段名和数据类型
开发语言·数据仓库·hive·c#
时光追逐者11 小时前
在 Blazor 中使用 Chart.js 快速创建数据可视化图表
开发语言·javascript·信息可视化·c#·.net·blazor
与火星的孩子对话12 小时前
Unity3D开发AI桌面精灵/宠物系列 【三】 语音识别 ASR 技术、语音转文本多平台 - 支持科大讯飞、百度等 C# 开发
人工智能·unity·c#·游戏引擎·语音识别·宠物
response_L12 小时前
国产系统统信uos和麒麟v10在线打开word给表格赋值
java·c#·word·信创·在线编辑
MasterNeverDown12 小时前
Swagger2Md:让WebAPI文档生成变得轻松高效
c#