如何在泛型参数中指定类和接口
本文关键字:接口 泛型 参数 | 更新日期: 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
对象中,您可以走泛型路线,并在单独的非泛型类上添加静态方法,该方法以泛型方式创建实例,并允许您避免命名泛型参数。
或者选择一个具体的类,因为过于泛型的代码不值得那么麻烦。
作为最后一个选项,您可以将所有函数重新实现为泛型和约束类型,只需为底层存储选择一种类型或另一种类型,并在取出时对其进行强制转换。
最根本的问题是需要一个类型来填充泛型参数。您需要投注并请其他人做出选择(泛型),或者选择存在的单一类型(因此View
或INavigationWrapper
)。
注意,如果你想让下列类型在一个布局中共存,无论你做什么,你都必须稍微改变类型安全的规则(比如为存储选择一个任意的基类)。
class View1 : View, INavigationWrapper
class View2 : View, INavigationWrapper