我正在研究泛型委托函数并声明List类型的返回类型。
public static List<T> PerformOperationOnGenericArray<T>(IList<T> myList,
FunctionForGenericArray<T> operation)
我能否使用泛型返回类型而不是List,它也指定泛型类型,即S
public static S<T> PerformOperationOnGenericArray<T, S>(IList<T> myList,
FunctionForGenericArray<T> operation)
我猜这是不可能的,但我看不出为什么不这样做的原因。当我指定时,编译器肯定知道类型:
PerformOperationOnGenericArray<int, List<string>>(myInts, i => i.Equals(12));
这可能是我需要考虑使用动态类型的情况吗?
答案 0 :(得分:3)
您不能将开放泛型类型用作泛型类型参数,但是,您可以使用特定类型S<T>
作为参数:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : S<T>
在您的情况下,如果类型S
在编译时是完全定义的(封闭类型),您甚至不需要这样做:
public static S<T> PerformOperationOnGenericArray<T>
(IList<T> myList, FunctionForGenericArray<T> operation)
应该足够了。
如果S
本身会有所不同,您只需要使用第一个表单。那我的意思是什么呢。我们来看一个例子。如果你有:
class Foo<T> { }
你可以写:
public static Foo<T> PerformOperationOnGenericArray<T>
(IList<T> myList, FunctionForGenericArray<T> operation)
但是,如果您有一组相关的泛型类型:
class Foo<T> { }
class Bar<T> : Foo<T> { }
class Baz<T> : Foo<T> { }
并且您希望允许调用者指定使用哪一个,然后您需要将返回类型作为该方法的通用签名的一部分:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : Foo<T>
调用者现在需要明确指定R
的类型:
PerformOperationOnGenericArray<T,Bar<T>>( ... )
如果您想允许接受单个参数的任何泛型类型,那么您就不幸了。类型系统没有提供表达限制的方法:
allow any generic type that allows a single parameter, and enforce that parameter to be a T
您可以做的最好的事情是定义一个众所周知的接口,所有已知类型都符合(如IEnumerable<T>
或您自己制作的接口),并将其用作通用约束的一部分:
public static R PerformOperationOnGenericArray<T,R>
(IList<T> myList, FunctionForGenericArray<T> operation)
where R : IEnumerable<T>
但是,在这种情况下,提供的类型必须都实现此接口。如果您正在寻找前者(您可以指定任何类型参数的数量必须匹配),那么您正在寻找通用duck typing (1) - 其中C#不支持。
这是一个有趣的旁注。创建一个通用方法,其类型不能由编译器单独从方法的形式参数推断出来,是试图避免的。当无法推断出参数时,调用者被迫指定所有类型参数 - 这会导致令人困惑和冗长的代码。虽然有时会出现这些情况,但最好尽可能避免使用它们。
(1) - 如果类型在类型,类型和名称中匹配,则C#支持在单个程序集中使用匿名类型进行鸭子类型输入成员 - 编译器将假定它们是相同的类型。