Is using generic interface justifies using another marker interfaces? - c#

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?

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();
}

Related

Fluent Interface for Generic Type Hierarchy

I believe this is the only way to achieve what I want but I wanted to put this out there to see if there's a solution that doesn't require using dynamic/reflection.
I have the following hierarchy of types, stripped to the bare essentials to demonstrate the point:
// Validators:
public abstract class Validator<T> { }
public class RequiredValidator<T> : Validator<T> { }
// Fields:
public abstract class Field { }
public abstract class Field<T> : Field
{
public void AddValidator(Validator<T> validator) =>
Console.WriteLine($"Added validator {validator.GetType()}");
}
public sealed class ValueField<T> : Field<T> { }
public sealed class ComputedField<T> : Field<T> { }
...many other field types that inherit Field<T>
This is an example usage of the fluent interface I want to achieve:
ValueField<string> field1 = new ValueField<string>().Required();
The Required() method must be available on all types that inherit Field<T>.
This is what I've come up with:
public static class Extensions
{
public static TField Required<TField, T>(this TField field) where TField : Field<T>
{
field.AddValidator(new RequiredValidator<T>());
return field;
}
public static TField DynamicRequired<TField>(this TField field) where TField : Field
{
DynamicAddRequiredValidator((dynamic)field);
return field;
}
private static void DynamicAddRequiredValidator<T>(Field<T> field)
{
field.AddValidator(new RequiredValidator<T>());
}
}
void Main()
{
// This is desired API usage but results in error:
// The type arguments for method 'Extensions.Required<TField,T>(TField)' cannot be inferred from the usage.
ValueField<string> field1 = new ValueField<string>().Required();
// This works but the user shouldn't have to specify types like this, makes it very annoying to use:
ValueField<string> field2 = new ValueField<string>().Required<ValueField<string>, string>();
// This works but requires dynamic:
ValueField<string> field3 = new ValueField<string>().DynamicRequired();
}
Am I missing a way of achieving this which avoids using dynamic based code?
Generics in C# are an all or nothing. You either pass all, like you've done, or none. It must be designed in a way that all arguments can be inferred. For what you're doing you can just use Field<T> instead of TField<T>, removing that generic type parameter; although it may not be as ideal. There are other ways... Some FLUENT designs return new types that contain the generics as properties allowing you to move forward but your continuation would need the logic of using that continue type as well. It gets a bit confusing but I feel you understand. If not let me know.
It would be nice if the where constraint could also help infer the types but it doesn't. Eric Lippert recently helped me understand that C# tries to infer the generic parameters only and if that can't be inferred it fails. The where constraint is only to limit the generic type to a base and inform developers. Although it does feel like we could also infer based on constraints, since we are basing the types, C# doesn't. Eric has an opinion about not doing so, which I'm sure is more than I understand ATM. Either way, there you have it.
For "extendable" fluent interface, we use following trick in Java (you can try, if it's possible in C# too):
public class Field<L extends Field<L, V>, V> {
public L required() {
//...
return (L) this;
}
}
public class ValueField<V> extends Field<ValueField<V>, V> {
}
Now you can call what you need:
ValueField<String> v = new ValueField<String>().required();
It's thanks to additional type parameter of Field which delegates specific return type of the fluent methods to children.

How can a class inherit from a parameterized version of itself?

I saw a C# class SomeClass that was defined like
public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
// ...
}
and I'm wondering how to translate that into English. The way I understand it seems logically impossible. How can a class inherit from a parameterized version of itself? Also, is this a common design pattern?
The key is to recognize that it's not inheriting from (or implementing) a parameterized version of itself, but rather inheriting from (or implementing) another class or interface, and using itself as a generic parameter for that target type.
For example, IComparable<T> says that there will be a CompareTo() method that takes an object of type T as a parameter. So by implementing IComparable<SomeClass> you're simply guaranteeing that a method with that signature will exist on this class:
public class SomeClass : IComparable<SomeClass>
{
public int CompareTo(SomeClass other)
{
//...
}
}
And yes, this is fairly common practice. Classes often implement the generic IComparable<> and IEquatable<> interfaces to show that they can be compared with other items of the same type. It's maybe also worth mentioning that enums in Java are declared as extending Enum<> of themselves--a pattern which is not common in C#, but does appear from time to time.
Translated in "English" it means: "Boy (or girl), you'd better be type-safe when implementing those interfaces, especially IComparable. Otherwise, you'll have to perform type casting, which I guess you don't want"
See the code below. SomeClass implemented IComparable and IComparable.
See differencies between implementations of CompareTo(object) and CompareTo(SomeClass).
namespace InterfacesStuff
{
internal class Program
{
private static void Main(string[] args)
{
var someClass1 = new SomeClass {ComparedValue = 1};
var someClass2 = new SomeClass {ComparedValue = 2};
//someClassObject defined as SomeClass
//object someClassObject = new SomeClass { ComparedValue = 2 };
//someClassObject defined as anything else but SomeClass
object someClassObject = 5;
int comparisonSomeClassBySomeClass = someClass1.CompareTo(someClass2);
int comparisonSomeClassByObject = someClass1.CompareTo(someClassObject);
}
}
public class SomeClass : IComparable, IComparable<SomeClass>, IEquatable<string>, IEquatable<int>,
IEquatable<double>
{
public int ComparedValue;
public int CompareTo(object obj)
{
var presumedSomeClassObject = obj as SomeClass;
if (presumedSomeClassObject != null)
{
if (ComparedValue <= ((SomeClass) obj).ComparedValue)
return -1;
}
return 0;
}
public int CompareTo(SomeClass other)
{
if (ComparedValue <= other.ComparedValue)
return -1;
return 0;
}
public bool Equals(double other)
{
throw new NotImplementedException();
}
public bool Equals(int other)
{
throw new NotImplementedException();
}
public bool Equals(string other)
{
throw new NotImplementedException();
}
}
}
It is not Inheriting, It is implementing the IComparable Interface. what is going on is
Someclass Implements the Icomparable and the IEquatable interface. Implementing an interface is like signing a contract stating you gaurentee that this class will implement the methods on an interface.
Icomparable msdn, IEquatable. If you look at the MSDN pages you can see that SomeClass gaurentees it will implement the methods in some fashion.
This is very common practice and it is many different names. The ones I hear most are programming by contract and Implementation over Inhertience. It lets you do a lot of cool things, like Dependency Injection, Proper Unit testing, better Generics. It does this because the compiler doesnt need to know the concrete class that your object is implementing. It just needs to know that it has certain functions on it. For further reading on this I would read Chapter one of the gang of four Design pattern book.
Wikipedia link Specifically the Introduction to Chapter one section
It doesn't really have to be convenient to express it in english for it to be valid code, although I'd probably read that as "SomeClass is comparable and equatable to itself". That doesn't really explain what's going on though, it's just a way of expressing it.
In C# types can be generic over categories of other types. Generic types are basically "type constructors". They take other types as parameters, and use them to construct new types. For instance, IEnumerable<int> and IEnumerable<string> are two completely different types. The non-generic version (IEnumerable) is a third one. In C# a type A can inherit ANY other type B as long as none of the following is true (I hope I didn't miss anything):
B is already a subtype of A
B is a class and A has already inherited another class
B is a struct
A is an interface but B is not
A is the same type as B
B is sealed
A is a struct and B is not an interface
This even makes the following code legal:
class Foo<T>
{
public T Value;
}
class Foo : Foo<int>
{
}
Foo and Foo<T> are different types, so there's no problem at all for one to inherit the other.
You can read more about generics here:
https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
And about inheritance here:
https://msdn.microsoft.com/en-us/library/ms173149.aspx
The code you posted does not inherit from any class. It is implementing certain so-called Interfaces. How to translate that snippet: "I guarantee that SomeClass will be Comparable and equatable with other SomeClass instances. I will provide definitions in this class on how to do that."
About specializing a class from some other class...
What you can do is something like this:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Pet
{
protected string name;
public Pet(String name)
{
this.name = name;
}
}
class Dog : Pet
{
private List<String> tricks;
public Dog(String name, List<String> tricks):base(name)
{
this.tricks = tricks;
}
}
class Program
{
static void Main(string[] args)
{
List<string> tricks = new List<string>();
tricks.Add("sit");
tricks.Add("jump");
tricks.Add("bark");
Dog puppy = new Dog("Fido", tricks);
}
}
}
Dog inherits from Pet. Dog calls Pet's constructor at creation. Whatever name you pass into Dog constructor, it will forward it to Pet constructor.
Because what happens is that a subclass first calls the constructor of its superclass with the appropriate arguments. Then it runs its own constructor. Whatever is declared as public or protected in a class will be visible to its subclasses.
Therefore Dog will have name and also a list of tricks:
You achieve this kind of view with the "Locals" window.
I recommend that you read some tutorials on c# inheritance, interfaces and generics

How to require subtypes of an abstract class to implement a static instantiator?

public abstract class A
{
// constructors omitted
public abstract A Create(SomeData data);
}
public class B : A
{
// constructors omitted
public override A Create(SomeData data)
{
return new B(data);
}
}
What I want is to be able to make the Create method static, so that I can get an instance of B without having to create a useless instance with an empty constructor. (If you're wondering why, A is actually a generic type of the form A<TFoo, TBar>, where TBar corresponds to the derived types. As we all know, you can't instantiate a generic type using a constructor that takes any arguments.)
I am already aware that static methods are decoupled from the object hierarchy, only relying on the name of the type. That means I can't have Create as an abstract method that I force all descendants to implement. Is there another way I can implement this pattern?
Something like this might work, depends on your requirements
public abstract class A
{
public string Data { get; set; }
public static T Create<T>(string data) where T : A, new()
{
return new T() { Data = data };
}
}
public class B : A { }
then can do
A foo = A.Create<B>("foo");
There is simply no way to do this. Inheritance is based off of instance methods in C# and has no equivalent feature for static methods. Another way to implement this pattern though is to require a lambda in lieu of a static method.
For example (you mentioned the actual type was A<TFoo, TBar>)
void UseIt<TFoo, TBar>(A<TFoo, TBar> p, Func<SomeData, TBar> func) {
TBar b = func();
...
}
The consumer doesn't care if Create is static, instance or even called create. Generally all they care about is having a function which takes a SomeData and returns a TBar. Delegates fit this pattern exactly.

Interface implementation that needs initiliazation

I would like to extract an interface of a class that needs initilization.
public class Example<T>
{
public Example(SomeData data)
{
// initialize self with data
}
public IEnumerable<T> GetObjects(SomeData data)
{
// extract data
}
}
The problem is that we can't write an interface that would enforce non-default type constructors. I could of course change my class to:
public interface IExample<T>
{
void Initilize(SomeData data);
IEnumerable<T> GetObjects(SomeData data);
}
public class Example<T> : IExample<T>
{
public void Initilize(SomeData data)
{
// initialize self with data
}
public IEnumerable<T> GetObjects(SomeData data)
{
// extract data
}
}
But this is not the same, because when one would instantiate this type could directly call into GetObjects which would then result in an exception that instance is not initilized.
What other options do I have?
As this is just an interface, you shouldn't care about the constructor. The interface defines what the implementations can do but not specifically how they do it or what order methods are called in.
How can you realistically say that in the future there won't be some implementation of the interface that works differently and doesn't require the constructor?
You don't. The constructor arguments are an implementation detail of the class- they are irrelevant to the interface unless you decide to make GetObjects a read/write property.
Somewhere you are constructing a concrete instance, and you already know about the class itself there, so you know that you need to pass certain constructor arguments.
If you really want to enforce this idea that "All IExamples must be constructed with some arguments" externally, use a Factory pattern:
public static class ExampleFactory {
public static IExample<T> MakeAnExample(SomeData data) {
// return some concrete implementation...
}
}

Generic List of Generic Interfaces not allowed, any alternative approaches?

I am trying to find the right way to use a Generic List of Generic Interfaces as a variable.
Here is an example. It is probably not the best, but hopefully you will get the point:
public interface IPrimitive<T>
{
T Value { get; }
}
and then in another class, I want to be able to declare a variable that holds a list of objects that implement IPrimitive<T> for arbitrary T.
// I know this line will not compile because I do not define T
List<IPrimitive<T>> primitives = new List<IPrimitives<T>>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive<X>
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive<Y>
Note that the T in IPrimitive<T> could be different for each entry in the list.
Any ideas on how I could setup such a relationship? Alternative Approaches?
public interface IPrimitive
{
}
public interface IPrimitive<T> : IPrimitive
{
T Value { get; }
}
public class Star : IPrimitive<T> //must declare T here
{
}
Then you should be able to have
List<IPrimitive> primitives = new List<IPrimitive>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive
John is correct.
Might I also suggest (if you are using C# 4) that you make your interface covariant?
public interface IPrimitive<out T>
{
T Value { get; }
}
This could save you some trouble later when you need to get things out of the list.
You say it won't work because you don't define T. So define it:
public class Holder<T>
{
public List<IPrimitive<T>> Primitives {get;set;}
}
This is one of the most complicated elements of the c# language though it is incredibly important for building well defined components. As such, c# falls short. However it is definitely possible to make this work.
The trick is to have 3 parts:
A non generic interface that contains all requirements of the interface.
A generic abstract class that implements the non generic interface and performs the type conversions as necessary.
A class that implements the generic abstract class with the appropriately typed results
For example:
public interface INonGenericInterface{
void Execute(object input);
object GetModel();
}
public abstract class IGenericInterfaceBase<T> : INonGenericInterface{
void INonGenericInterface.Execute(object input){
Execute((T) input);
}
object INonGenericInterface.GetModel(){
return GetModel();
}
protected abstract void Execute(T input);
protected abstract T GetModel();
}
public class ImplementingClass : IGenericInterfaceBase<ModelClass>{
protected override void Execute(ModelClass input){ /*Do something with the input */ }
protected override ModelClass GetModel(){ return new ModelClass();}
}
//Extras for demo
public class ModelClass { }
public class ModelClass2 { }
public class ImplementingClass2 : IGenericInterfaceBase<ModelClass2>
{
protected override void Execute(ModelClass2 input) { /*Do something with the input */ }
protected override ModelClass2 GetModel() { return new ModelClass2(); }
}
var agi = new INonGenericInterface[] { new ImplementingClass(), new ImplementingClass2() };
agi[0].Execute(); var model = agi[0].GetModel();
agi[1].Execute(); var model2 = agi[1].GetModel();
//Check the types of the model and model2 objects to see that they are appropriately typed.
This structure is incredibly useful when coordinating classes w/ one another because you're able to indicate that an implementing class will make use of multiple classes and have type checking validate that each class follows established type expectations. In addition, you might consider using an actual class instead of object for the non-generic class so that you can execute functions on the result of the various non-generic calls. Using this same design you can have those classes be generic classes w/ their own implementations and thus create incredibly complex applications.
To OP: Please consider changing the accepted answer to this to raise awareness of the correct approach as all previously stated answers fall short for various reasons and have probably left readers with more questions. This should handle all future questions related to generic classes in a collection.

Categories

Resources