0

Let's assume I have an interface that has some method parametherized with another interface:

interface IFeature<T> where T : IFeatureParameters { CustomObject Apply(CustomObject obj, T featureParameters); } 

But features are so much different that there is nothing common in their parameters so IFeatureParameters interface is in fact marker interface. It just forces developers in future to create Feature and FeatureParameters implementations in pairs.

As far as I googled, marker interfaces are considered to have no reasons to exist in custom code.

Is it suitable to use marker interfaces in my case? If not, what may substitute it?

12
  • 1
    If IFeatureParameters has neither properties nor methods, why does Apply even care? Commented Aug 27, 2019 at 10:33
  • Is IFeature itself even meaningful? Without the interface it essentially reduces to object Apply(object, object), which suggests absolutely nothing about how it should be implemented or used. If used only in a few places (or even just one) it sounds like the sort of thing a single well placed Func might also do. Commented Aug 27, 2019 at 10:33
  • @JeroenMoster, fair enough. The reason I wanted to implement it is to create some kind of "uses-a" relationship between IFeature and IFeatureParameters and bind them together. And to force others who write implementations of those interfaces to implement both interfaces for one purpose. To avoid situations when OneFeatureParamers are passed into AnotherFeature.Apply Commented Aug 27, 2019 at 10:45
  • @ThomasSchremser, you're right, it has not. But its implementation would. And the interface is just used for the purposes descriped in the comment above. Commented Aug 27, 2019 at 10:47
  • 1
    @zaitsman, ok, now it sounds very reasonable. How do you think, should I leave the question as it is or just delete it? Commented Aug 27, 2019 at 11:45

1 Answer 1

1

An interface IFeatureParameters has no added value here. Whether or not a class (or whatever type you like) is a valid type to pass parameters to a feature, is entirely determined by the feature implementation. Every time a developer makes a new implementation of interface IFeature, they will specify explicitly what is the correct parameter type, by filling in the type variable T. That is enough to ensure no 'alien' types will be passed into an implementation of method Apply.

Here is a simple example.

public class FeatureParametersA { public string SomeText; } public class FeatureParametersB { public int SomeNumber; } 

I could have made these classes implement an interface IFeatureParameters, but that is not required.

public interface IFeature<T> { CustomObject Apply(CustomObject obj, T par); } public class FeatureA : IFeature<FeatureParametersA> { public CustomObject Apply(CustomObject obj, FeatureParametersA par); { obj.Add(par.SomeText); return obj; } } public class FeatureB : IFeature<FeatureParametersB> { public CustomObject Apply(CustomObject obj, FeatureParametersB par); { obj.Add(par.SomeNumber.ToString()); return obj; } } 

Notice how each class has its own dedicated implementation of Apply, specific for the related 'parameters' type. Everything is strongly typed, so the compiler will prevent anyone from trying to pass the wrong type into Apply.

For completeness:

public class CustomObject { public void Add(string s) { _sb.AppendLine(s); } private StringBuilder _sb = new StringBuilder(); } 
Sign up to request clarification or add additional context in comments.

2 Comments

Ok, but to finally catch the idea (maybe it's not fully related to the question, but still): Imagine my next step is to create a pipeline of applying those features. For those purposes I create new interface IFeaturePipeline which contains something like IList<IFeature<===>> Features { get; } . Which type should be used instead of ===? Just object? And so I do not restrict it anyhow at compile time?
Generics are resolved in compile time. You can make a list of IFeature<T>, but that means T is the same for the entire list. If you need a list of features with varying implementations, then there are two possibilities. (1) Don't use generics; use interfaces instead. (2) Wrap IFeature<T> in a class that hides away T. That implies you will not be able to access method Apply through the pipeline.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.