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}");
    }
}
相关推荐
rockey6273 小时前
AScript如何实现中文脚本引擎
c#·.net·script·eval·expression·function·动态脚本
我是唐青枫5 小时前
C#.NET gRPC 深入解析:Proto 定义、流式调用与服务间通信取舍
开发语言·c#·.net
unicrom_深圳市由你创科技5 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
昵称暂无16 小时前
.NET 高级开发 | i18n 原理、实现一个 i18n 框架
javascript·c#·.net
疯狂成瘾者7 小时前
Chroma向量数据库
开发语言·数据库·c#
我是唐青枫7 小时前
C#.NET Monitor 与 Mutex 深入解析:进程内同步、跨进程互斥与使用边界
开发语言·c#·.net
ou.cs7 小时前
c# 信号量和锁的区别
开发语言·c#
yugi9878387 小时前
C# 串口下载烧写BIN文件工具
开发语言·c#
"菠萝"8 小时前
C#知识学习-021(文字关键字)
开发语言·学习·c#
游乐码8 小时前
c#HashTable
开发语言·c#