Interface implementation that needs initiliazation - c#

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...
}
}

Related

Is using generic interface justifies using another marker interfaces?

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

Forcing partial base Initialization (and methods) in Inherited Class Constructor C# (like abstract does to methods) - work around to do it

I am having a C# abstract class which have some methods to be implemented by its children.
Though it is so, the initialization values for those children consist of two parts: one which is the same as the parent, and another one which is unique to the children.
public abstract class parentClass {
public abstract bool IsInputValid(string input); //children must implement this
public parentClass () {
//Some shared initialization
}
}
If the class is not abstract we could do something like this to implement that
public class parentClass {
public parentClass (string input) {
//Some shared initialization
}
}
public class childClass : parentClass {
public childClass (string input) : base (input) {
//Some unique initialization
}
}
But that cannot be done using abstract class and some more, the method not need not to be implemented (since it is not abstract).
So I am in a dilemma here. On one hand, I want to have some base initialization called and on the other, I also want to have some methods enforced.
So my question is, how do we normally implement such case? On one hand it is enforcing some base initialization, and on another some methods.
Note: I am new to abstract class so I would be glad to receive any inputs regarding it.
Where do I declare wrongly (if any)? If we cannot do so, is there a way to get around to produce the same result (that is, to enforce the child class to use certain signature for constructor)?
There should be no need to enforce this. You say that the base class has some common initialization and the child classes have their own specialized initialization as well.
This is enforced already, if you have this:
public abstract class Base
{
protected Base(int value) { ... }
}
Then you have a couple of guarantees:
Nobody can construct an object of the type Base since it is abstract
Nobody can construct an object that inherits from Base without indirectly calling the only existing constructor of Base, that takes an int value parameter.
The last part there is important.
A child class can deal with this type of base constructor in at least three ways:
It can provide a constructor that looks identical save the name of it, just passing the value down to the base constructor:
public class Child : Base
{
public Child(int value) : base(value) { ... }
}
It can provide a constructor that has this parameter but has additional parameters to the child class constructor as well:
public class Child : Base
{
public Child(int value, string other) : base(value) { ... }
}
It can provide a constructor that doesn't have the parameter to the base class, but manages to compute this parameter:
public class Child : Base
{
public Child(string other) : base(other.Length) { ... }
}
The last part also handles the case where the child constructor has no parameters at all:
public class Child : Base
{
public Child() : base(new Random().Next(100)) { ... }
}
Regardless of which approach you use, it is impossible to call the base class constructor without passing a value for that parameter, hence you have enforce the following:
Child classes has to be aware of the base class constructor and its parameter
But you cannot, and should not, try to enforce the presence of a particular constructor with a specific signature.
Now, having said that, what if you want to create some sort of common way to construct two distinct child classes, that has such different constructors, in such a way that code that uses them doesn't need to know the specifics of either constructor?
Enter the factory pattern (Wikipedia):
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
(quoted text copied from entry paragraph in the Wikipedia-article)
Here's a way to abstract away the presence and knowledge of such different constructors and child classes:
void Main()
{
Test(new Child1Factory());
Test(new Child2Factory());
}
public void Test(IBaseFactory baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory.Create();
}
public class Base
{
public Base(int value)
{
Console.WriteLine($"Base.ctor({value})");
}
}
public interface IBaseFactory
{
Base Create();
}
public class Child1 : Base
{
public Child1(int value) : base(value)
{
Console.WriteLine($"Child1.ctor({value})");
}
}
public class Child1Factory : IBaseFactory
{
public Base Create() => new Child1(42);
}
public class Child2 : Base
{
public Child2(string name) : base(name.Length)
{
Console.WriteLine($"Child2.ctor({name})");
}
}
public class Child2Factory : IBaseFactory
{
public Base Create() => new Child2("Meaning of life");
}
Pay special attention to the Test(...) method, as this has no knowledge of which Base child it will get, nor how to construct such an object. If you later on add new child types from Base, you will have to provide new factories as well but existing code that uses these factories should not need to be changed.
If you want a simpler factory pattern all you have to do is replace the interface and factory classes with a delegate:
void Main()
{
Test(() => new Child1(42));
Test(() => new Child2("Meaning of life"));
}
public void Test(Func<Base> baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory();
}
Final note here. Since the factory pattern means you will have to create a different type that does the actual construction of the object you can enforce the signature of that other type, either by
Adding parameters to the Create method on the factory interface
Specifying a delegate that has parameters to the factory delegate
This means you can enforce the signature of "the creation process". Still, you cannot enforce the presence or signature of a particular constructor, but the constructor is just a means to an end, create an object, and with the factory pattern you can actually formalize this pattern in your code and thus you should get what you want.
You cannot enforce the signature or even existence of constructors of your derived classes. (or any class for that matter)
I'm afraid that's the end of the story. You aren't doing anything wrong, it's just not possible.
Since you can't override constructors in c#, you cannot enforce the existence of a certain constructor in the derived class .
This means:
a constructor cannot be abstract, virtual etc
constructors aren't polymorphically
You cannot have an abstract constructor, but neither is there any need to.
All you need to do is remove the "abstract" keyword from your parentClass and you should be good to go.

Overriding (shadowing, overloading?) methods with different return types in a C# hierarchy

I'm writing an SDK which has an OOP structure for implementing data types;
first an interface
then an abstract implementation
finally an abstract generic implementation
People can choose to implement either the interface, or derive from either of the classes.
public interface IGoo
{
IGoo Duplicate();
...
}
public abstract class Goo : IGoo
{
IGoo IGoo.Duplicate() {
return Duplicate();
}
abstract public Goo Duplicate();
...
}
public abstract class Goo<T> : Goo
{
abstract public Goo<T> Duplicate(); ??????
...
}
I'd like to re-implement the Duplicate method so that it always returns the most specific type possible. I.e. when you call Duplicate on an IGoo instance, you get another IGoo. If you call it on Goo, you get Goo, if you call it on -say- Goo<int>, you get Goo<int>. And all Duplicate() methods always call the most specific implementation.
Is this possible? Is it only possible when you can implement an interface explicitly? In which case, should I not make Goo<int> derive from Goo, but have it implement IGoo instead and type all the low-level functionality twice?
What about the following?
public interface IObj
{
IObj Duplicate();
}
public abstract class Obj : IObj
{
public Obj()
{
}
public virtual IObj Duplicate()
{
return this;
}
}
public abstract class ObjT<T> : Obj
{
public ObjT()
{
}
public override IObj Duplicate()
{
return this;
}
}
public class ObjImpl : Obj
{
}
public class ObjTImpl : ObjT<int>
{
}
I understand that you want it to return the most specific type possible in any inheriting class but it actually is. It's boxing the inheriting type into the interface (or a raw object if you where to return objects instead of interface types. If you run the following test in a console app you will see the proper type is represented:
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
ObjImpl a = new ObjImpl();
ObjTImpl b = new ObjTImpl();
Console.WriteLine(a.Duplicate().GetType());
Console.WriteLine(b.Duplicate().GetType());
Console.ReadLine();
}
}
}
// outputs:
// ObjImpl
// ObjTImpl
The idea of redefining abstracts of abstracts goes against the purpose of abstract polymorphism. If the derived types do not intend to implement the inherited abstract member, they should not be inheriting it.
Although the example I gave above would require casting to access any child class-specific members, it would be the proper way to do it in this approach. The runtime needs to know what types it should expect to deal with.
There is always dynamics you could play around with but to be honest I haven't played around with dynamics with generics and inheritance as I suspect I would make my compiler cry, and when it cries, I cry, a little bit deep down inside... lol
It is only possible when you implement the interface explicitly. That's because the return type of a method is not part of its signature - which the compiler checks when overloading. Therefore, otherwise identical methods which only differ in their return type are syntactically not possible.

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.

Specify generic type as argument param without knowing T

I'm approaching a problem while still having some ignorance regarding Generics and their proper declarations / uses. I get the premiss, but some of the ins-n-outs of generics still elude me.
Given the following code (does not compile and contains code-smell):
public interface IUIConcern<out T> where T : IUIConcernExtension
{
string Name { get; }
Func<T> Extend();
}
public class UIConcern
{
public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns{
get {
// Logic...
}
set {
// Logic...
}
}
}
... I have a few questions:
Why do I have to specify this part public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
with a constraint when I have already constrained the T in the declaration public interface IUIConcern<out T> where T : IUIConcernExtension
How can I have a property that holds a List<> of my IUIConcern<T> without knowing T other than knowing it will be derived from IUIConcernExtension?
Again, I realize this doesn't compile and is not correct, just looking to see how I can hold a list of generic items that may have many different type of IUIConcern<> elements.
Thank you!
You need to have a base interface, for instance:
public interface IUIConcern
{
string Name { get; }
}
public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
Func<T> Extern();
}
How you would define Concerns and Register would depend on how you treat T. Alternatively if you only deal with instances where you know T, you could use a Dictionary<Type, List<IUIConcern>> to hold anything, or potentially drop the base interface and just store using object depending on what you need in your controller code.
The problem is not located at the interface, but the problem is because of your generic implementation using static methods and properties.
The answer from Guvante was correct when saying that you need to define the IUIConcernExtension, but that is of course very logical, so im assuming you have just omitted that part since it does not matter for the issue you are facing.
The problem in the code is that you have created a class that has static methods and procedures, with the generic definition not laying at class level, but at methods level, because of this, the property that has and the Method cannot assume you are always with the same type!!
Lets say you call call :
Register<string>("something", UIConcern<string>)
but before that you have already called:
Register<Type>("something", UIConcern<Type>)
How could the compiler allows you to that?! So the answer is to define the generic type at class level, with this all properties and methods will be of same .
Also you need to use a private member for your list, since you doing everything static, the correct code should be:
interface IUIConcernExtension
{
string Name { get; }
}
public interface IUIConcern<out T> where T : IUIConcernExtension
{
Func<T> Extend();
}
public class UIConcern<T> where T : IUIConcernExtension
{
private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>();
public static void Register(string concernName, IUIConcern<T> uiConcern)
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns
{
get { return _Concerns; }
set { _Concerns = value; }
}
}

Categories

Resources