c# - 抽象泛型类型变量的声明

标签 c# generics abstract-class

我的问题如下。我为一个显然不起作用的家庭项目做了代码设计。也许你能帮我弄清楚“代码味道”是从哪里来的。

好的,让我们开始吧: 我已经定义了一些类来包装不同类型的存档类型:

public abstract class Archive { }
public class ZipArchive : Archive { }
public class TarArchive : Archive { }

为了处理这些文件,我定义了管理器类。 定义所需行为的抽象,

public abstract class ArchiveManager<T> where T : Archive
{ 
    public abstract void OpenArchive(T archive);
}

具体的,实际实现了特定的行为:

public class ZipArchiveManager : ArchiveManager<ZipArchive>
{
    public override void OpenArchive(ZipArchive archive) {  /* .. */ }
}

public class TarArchiveManager : ArchiveManager<TarArchive>
{
    public override void OpenArchive(TarArchive archive) {  /* .. */ }
}

现在发生的事情是在编译期间,我不知道我将处理哪种存档,所以我尝试了以下操作:

class Program
{
    static void Main(string[] args)
    {
        ArchiveManager<Archive> archiveManager = null;

        if (/*some condition*/) {            
            archiveManager = new ZipArchiveManager();
        }
        else {
            archiveManager = new TarArchiveManager();
        }
    }
}

最终出现以下错误:

Cannot implicitly convert type 'ZipArchiveManager' to 'ArchiveManager'

据我所知,泛型参数不能被隐式转换。有什么办法可以解决这个问题吗?这个代码/设计“有味道”吗?

非常感谢您。

最佳答案

您可以使用逆变接口(interface)代替不实现任何功能的抽象类。在这种情况下,您只能将类型参数用作方法的返回值,而不能用作参数:

public interface IArchiveManager<out T>
    where T : Archive
{
    T OpenArchive(Stream stream);
}

然后,只需在您的管理器类中实现该接口(interface):

public class ZipArchiveManager : IArchiveManager<ZipArchive>
{
    public ZipArchive OpenArchive(Stream stream)
    {
        // ...
    }
}

public class TarArchiveManager : IArchiveManager<TarArchive>
{
    public TarArchive OpenArchive(Stream stream)
    {
        // ...
    }
}

关于c# - 抽象泛型类型变量的声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10160876/

相关文章:

c# - 如何在包含 n 个字符的子字符串上对字符串进行切片 c#?

java - 如何使用带有 groovy 闭包的构造函数参数实例化 Java 抽象类

c# - 获取最后一个斜杠后的内容

swift - 子类类型作为闭包参数

c# - SignalR:我无法从服务器调用 .net 客户端方法

带有通配符的 Java 抽象泛型方法用具体类型实现

java - 将方法从抽象类转移到接口(interface)以改进代码设计

c++ - 基类的派生类充当抽象类

c# - Facebook 社交图谱 API : "Annoying or Abusive" Error Message

c# - 在 C# 中构建唯一对象列表的最佳方法