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}");
    }
}
相关推荐
暗暗别做白日梦37 分钟前
Pulsar 消息同步机制
c#·linq
海盗12341 小时前
微软技术周报——2026-07-22
microsoft·c#·.net
海盗12341 小时前
微软技术日报 ——2026-07-21
microsoft·c#·.net
-银雾鸢尾-1 小时前
C#中的泛型约束
开发语言·c#
WWJA王文举1 小时前
单片机参数如何掉电保存:Flash、EEPROM和配置存储完整设计
数据库·stm32·mongodb·c#
czhc11400756633 小时前
722:零侵入;DBG;
c#
-银雾鸢尾-12 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-12 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
心平气和量大福大16 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
白露与泡影16 小时前
Arthas 实战指南:从方法耗时定位到 JVM 变量热修改
服务器·jvm·c#