C # Is it possible to create optional generic constraint types

I think I know the answer to this question, but I need to point out that the general method can take a type based on two optional restrictions. It is that T can be either this or that type.

public WebPage Click<T>(Func<WebPage> predicate) where T : LinkBase || FieldBase, new() { WebDriver.FindElement(new T().LinkPath).Click(); WebDriver.Wait(); return predicate.Invoke(); } 

I know there is currently no such syntax, but is there a way to solve this problem without duplicating the method to restrict on both types? If not, is it in the areas of opportunity for a future version of the language?

+7
source share
3 answers

You are right, there is no way to pass multiple types into a common method.

Do you have control over both types? Can you force them to implement the same interface or abstract class?

+2
source

Doing this does not make sense if LinkBase and FieldBase do not have a common base or implement a common interface. And if they do, then you can just use it as a limitation.

I say that this does not make sense, because the very reason for using type restrictions is to make sure that the actual type type used supports the well-known public interface (otherwise you could just do everything-generating and using object ) . But if you have a hypothetical "or" constraint, how can the compiler make sure that the code you write inside the general will really be significant for a type parameter that ends?

+6
source

One option for such problems is to apply an adapter pattern to your classes. In this case, they have the same properties, but not the same interface. (This is most useful if you do not control the source code or otherwise it makes no sense for them to actually use the interface in normal scripts.)

 interface ILinkablePath { string LinkPath { get; } } class LinkBaseAdapter : ILinkablePath { private LinkBase linkBase; public LinkBaseAdapter(LinkBase linkBase) { this.linkBase = linkBase; } public string LinkPath { get { return this.linkBase.LinkPath; } } } 

You can write an adapter for each class that you want to support. If they don’t have a common interface and may not even have common methods or properties (in the name, if not in execution), you can use this method if you want to use classes in the same way.

When you do this, you can fully work with the adaptation interface in your methods.

Otherwise, for your specific problem, you can simply create different methods for each type that you want to support, or (if you just work with a single property, and not with the rest of the object), just go to the value of the property you want to use, not the entire object.

+2
source

All Articles