如何在泛型参数中指定类和接口

本文关键字:接口 泛型 参数 | 更新日期: 2023-09-27 18:05:19

我有一个类,需要布局View实现INavigationWrapper。如果我这样定义它:

public class NavigationStackLayout : Layout<T> where T : View, INavigationWrapper

那么我需要在其他地方指定T。如果我这样定义它:

public class NavigationStackLayout : Layout<View>

public class NavigationStackLayout : Layout<INavigationWrapper>

则类的子类缺少其类型的一部分。如果我这样定义它:

public class NavigationStackLayout : Layout<View : INavigationWrapper>

就是语法错误。如何在泛型参数中指定类和接口,而不需要指定特定的子类?

更新:

要明确,我不拥有Layout<T>,所以我不能只是添加泛型方法到我的非泛型类;我需要使用Layout<T>现有的方法。我知道它们会起作用的,因为Layout<T>的约束是where T : View

我正在寻找一个解决方案,将使以下工作:

class View1 : View, INavigationWrapper {}
class View2 : ContentView, INavigationWrapper {} // ContentView is a subclass of View
class View3 : View
var stack = new NavigationStackLayout();
stack.Add(new View1()); // this works
stack.Add(new View2()); // this also works
stack.Add(new View3()); // this fails at compile time

如何在泛型参数中指定类和接口

假设您可以只将单个类放入每个NavigationStackLayout对象中,您可以走泛型路线,并在单独的非泛型类上添加静态方法,该方法以泛型方式创建实例,并允许您避免命名泛型参数。

或者选择一个具体的类,因为过于泛型的代码不值得那么麻烦。

作为最后一个选项,您可以将所有函数重新实现为泛型和约束类型,只需为底层存储选择一种类型或另一种类型,并在取出时对其进行强制转换。

最根本的问题是需要一个类型来填充泛型参数。您需要投注并请其他人做出选择(泛型),或者选择存在的单一类型(因此ViewINavigationWrapper)。

注意,如果你想让下列类型在一个布局中共存,无论你做什么,你都必须稍微改变类型安全的规则(比如为存储选择一个任意的基类)。

class View1 : View, INavigationWrapper
class View2 : View, INavigationWrapper