首页 > 解决方案 > 是否可以使用其他泛型类型的泛型参数

问题描述

是否可以使用来自另一个泛型类型的泛型参数,并推断使用的用法如下:

public class TypeA<T2> { }

public class TypeB<T1, T3, T2> where T3 : TypeA<T2> {}

public class Test
{
    public Test()
    {
        // works but kind of ugly...
        new TypeB<string, TypeA<int>, int>();

        // Is it possible somehow to infer the TypeAType from the implemented generic generic type so I can use it like this?
        new TypeB<string, TypeA<int>>();
    }
}

标签: c#generics

解决方案


简短的回答是否定的,因为 C# 不支持“泛型上的泛型”。

为了解释这意味着什么,让我向您展示一个更具体的例子:

List<int> list = new List<int>();
HashSet<int> set = list.To<HashSet<int>>();

在这里,扩展方法To()是一段神奇的代码,可以将一种容器类型转换为另一种容器。

假设 C# 支持此功能,人们会天真地尝试像这样定义该方法:

public static class EnumerableExtensions {
    public static TContainer<TItem> To<TContainer<TItem>>(
        this IEnumerable<TItem> source)
        where TContainer: IEnumerable {
        // magic
    }
}

这当然不会编译,因为 C# 无法解析本身是泛型的泛型类型参数 ( TContainer<TItem>)。

这整个概念被称为C# 不支持的更高种类的多态性(或更高种类的类型)。不过,它可能会在未来出现,您可以在此 GitHub 问题中跟踪进度。

有一个名为LanguageExt的 Nuget 包,它提供了一些更高级的类型,如果我没记错的话,它会做同样的事情:显式声明内部类型,以便类型推断可以使用它。


推荐阅读