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}");
    }
}
相关推荐
c#上位机1 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya1 小时前
一些写leetcode的笔记
笔记·leetcode·c#
IT规划师2 小时前
C#|.net core 基础 - 扩展数组添加删除性能最好的方法
c#·.netcore·数组
时光追逐者2 小时前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff3 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
__water11 小时前
『功能项目』回调函数处理死亡【54】
c#·回调函数·unity引擎
__water11 小时前
『功能项目』眩晕图标显示【52】
c#·unity引擎·动画事件
__water12 小时前
『功能项目』第二职业法师的平A【57】
c#·unity引擎·魔法球伤害传递
__water14 小时前
『功能项目』战士的伤害型技能【45】
c#·unity引擎·战士职业伤害型技能
君莫愁。15 小时前
【Unity】检测鼠标点击位置是否有2D对象
unity·c#·游戏引擎