简体   繁体   中英

How do I specify a class and an interface in a generic parameter?

I have a class which needs to lay out View s which implement INavigationWrapper . If I define it like so:

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

then I need to specify T everywhere else. If I define it like so:

public class NavigationStackLayout : Layout<View>

or

public class NavigationStackLayout : Layout<INavigationWrapper>

then the class' children are missing part of their type. If I define it like so:

public class NavigationStackLayout : Layout<View : INavigationWrapper>

then that's a syntax error. How do I specify a class and an interface in a generic parameter, without needing to specify a particular subclass?

UPDATE:

To be clear, I don't own Layout<T> , so I can't just add generic methods to my non-generic class; I need to use Layout<T> 's existing methods. I know they'll work, because the constraint on Layout<T> is where T : View .

I'm looking for a solution which will make the following work:

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

Assuming you are okay with only putting a single class into each NavigationStackLayout objects you could go the generic route and add a static method on a separate non-generic class that creates an instance in a generic way and allows you to avoid having to name the generic parameter.

Alternatively pick a concrete class since overly generic code isn't worth that much of a hassle.

As a final option you could reimplement all the functions as being generic and constraining the type, just pick one type or the other for your underlying storage and cast it when you take it out.

The fundamental problem is that you need a type to fill in a generic parameter. You need to either punt and ask someone else to make a choice (generic) or select a single type that exists (so either View or INavigationWrapper ).

Note that no matter what you do if you want the following types to coexist in a single layout you are going to have bend the rules on type safety a little (such as pick an arbitrary base class for storage).

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM