What is the best way to implement a strategy for the constructor of a template/abstract class in C#?
I have several classes which are all based on parsing a string inside the constructor.
The parsing is done in a static method which creates list of key value pairs and is common for all classes, but some fields are also common for all classes - thus I use a abstract template class.
The problem is that I do not see a way to inherite the implementation of the constructor of the abstract base class. Otherwise I would implement the constructor strategy in the base class and would force the handling of the lists inside some abstract methods.
Edit:
Added Not working code for the template class
public abstract class XXXMessageTemplate
{
public XXXMessageTemplate(string x) // implementation for the constructor
{
Parse(x);//general parse function
CommonFields();//filling common properties
HandlePrivateProperties();//fill individual properties
HandlePrivateStructures();//fill individual structures
}
abstract void HandlePrivateProperties();
abstract void HandlePrivateStructures();
}
The actual messages should not implement any constructor and only implement the HandlePrivateProperties and HandlePrivateStructures functions.
If you want the logic of the base class constructor to run in the derived class, you'd normally just call up to it:
public Derived(...) : base(...)
{
// ...
}
The base class can call abstract/virtual methods during the constructor, but it's generally frowned upon as the derived class's constructor body will not have been executed yet. (You'd want to document this really emphatically.)
Does this answer your question? I'm not entirely sure I understand the issue - some pseudo-code would help.
EDIT: The derived classes have to implement constructors. Constructors aren't inherited. If you don't specify any constructor, the compiler will provide a parameterless constructor which calls a base parameterless constructor. However, you can easily write a constructor with the same signature and just call the base class constructor:
public Derived(string x) : base(x)
{
// Base constructor will do all the work
}
Provide a constructor for the base class and use it in the derived classes:
abstract class Base {
// ...
protected Base(string commonField) {
CommonField = commonField;
}
}
class Derived1 : Base {
public Derived1(string commonField, string specificField) : base(commonField) {
SpecificField = specificField;
}
}
I am not 100% sure I understand the question fully, but do you mean that you want your subclasses to pass a literal string to the base, as in this example?
public class MyMessage : XXXMessageTemplate
{
public MyMessage() : base("MyMessage String")
{
}
public override void HandlePrivateProperties()
{
// ...
}
public override void HandlePrivateStructures()
{
// ...
}
}
As I can see the problem is in Parse(...) method. Not in the method itself but in his existence. You have some raw data (string x) which must be converted into structured data (key value pairs) before use to construct objects. So you need somehow pass structured data into base and child constructors. I see 3 approaches:
Parse data in base class and use protected base property to pass it to childs.
Parse data before calling constructor.
Parse data in place of usage.
1
You may extend an Mehrdad answer via additional protected property which holds parsed args. Something like:
abstract class Base {
protected ParsedData ParsedData;
// ...
protected Base(string x) {
ParsedData = Parse(x);
CommonFields(); //initialize common fields using ParsedData
}
}
class Derived1 : Base {
public Derived1(string x) : base(x) {
DerivedFields(); //initialize specific fields using ParsedData
}
}
2
Or you can pass pre parsed string into constructor:
abstract class Base {
protected ParsedData ParsedData;
// ...
public static ParsedData Parse(string x)
{
//Parse x here...
}
protected Base(ParsedData data) {
CommonFields(data); //initialize common fields using data
}
}
class Derived1 : Base {
public Derived1(ParsedData data) : base(data) {
DerivedFields(data); //initialize specific fields using data
}
}
3
Or parse in place of usage:
abstract class Base {
// ...
protected Base(string x) {
var data = Parse(x);
CommonFields(data); //initialize common fields using data
}
}
class Derived1 : Base {
public Derived1(string x) : base(x) {
var data = Parse(x);
DerivedFields(data); //initialize specific fields using data
}
}
Related
I have a base abstract class that calls a private validation method in constructor. For part of its descendants I want to skip this check. This class have too many usages and I can't move the validation from the base class.
Which is better solution
create an empty interface, implemented in classes that will skip this check
expose this property and make it protected virtual and override it with empty body in derived classes that should skip the check
(any other better solutions will be also appreciated)
If this consideration applies only to this class, the 2nd approach I'd choose. If it will be the case in more classes, therefore it would represent some behaviour independent of class, I would go with 1st option (then also you can make use of polymorphism in cases, where you want to use just classes without check).
public abstract class BaseClass {
public BaseClass(bool? validate = true) {
if (validate.HasValue && validate.Value) {
Validate();
}
}
private void Validate() { }
}
public class ChildClass1 : BaseClass {
public ChildClass1() : base() { }
}
public class ChildClass2 : BaseClass {
public ChildClass2() : base(false) { }
}
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.
I have an abstract class:
public abstract class ExampleBase : IExampleBase
{
protected ExampleBase()
{
this.SetupData();
}
protected abstract Dictionary<int, Adress> RelevantData { get; set; }
protected abstract void SetupData();
public void ProcessData()
{
// use RelevantData
}
}
And a derived class:
public class Example : ExampleBase
{
public Example()
{
}
protected override void SetupData()
{
this.RelevantData = new Dictionary<int, Adress>
{ 1, new Adress { ... } },
{ 2, new Adress { ... } }
}
}
In the base class, ReSharper tells me
Virtual member call in constructor
I understand that it's dangerous to call the method because of the execution order.. but how can I resolve this issue?
Context: I want to set up data in each derived class which will then be processed in the base class. I wanted to call the SetupData() method in the base class since it's the same in every derived class.
Derived class:
Set up the data
Base class:
Process the data
You don't. You accept the fact this is dangerous, and (try to) prevent this. This is a design flaw!
You could prevent this for example by moving the call to the highest level class, or make every class responsible for it's own, thus removing the unsafe part of the method call. Then you don't need another class (a base class) to take responsibility for its deriving classes.
If that isn't possible. Make very clear using comments or any other method available that the developer should take this problem into account when updating the code.
Call SetupData in the constructor of Example (and every other derived class) not ExampleBase and make Example a sealed class.
The problem is that SetupData could access something that would be initialized by the Example constructor. But the Example constructor is called only after ExampleBase constructor has finished.
Your base class constructor is called first. If your override method in your subclass depends on anything done in its constructor it won't work. Personally I'd look for a different design, maybe passing the abstract class into the derived class rather than using inheritance.
So a couple lines of code in every derived class
If you need to control the process order then you can do this
public abstract class MyBase
{
public void ProcessData()
{
bool processData = true;
}
public MyBase()
{
bool myBase = true;
}
public MyBase(int pass)
{
bool myBase = true;
}
}
public class Example : MyBase
{
public void GetData() {}
public Example()
: base(1)
{
bool example = true;
GetData();
ProcessData();
}
}
Well, originally I had a couple of constants (like MAX_SPEED) with different values in every of the derived classes. The idea was to use those values in some methods of the base class. That's when I realized that I cannot do that with constants, so I created read-only properties.
I need a method to assign those values to private fields at the moment of the instantiation, preferably in the base class. But first I have to assing the original values in derived classes. Since those are properties, I couldn't find a way to initialize them while defining, so the only way to do that is in the derived constructors.
That's where the problem comes: values are initialized after their assigning to private fields in the base class. The solution I get away with is to create a virtual method and to do assigning there.
Is there a way to call a base constructor from derived class so that the code from derived constructor will be invoked first?
class BaseClass
{
public BaseClass()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
System.Console.WriteLine("This should be shown first");
}
}
Of course in the example it would work the other way around. Is there a solution?
No. The base class constructor is always executed before the body of the derived class constructor. However:
Any instance variable initializers in the derived class are executed before the base class constructor
The base class constructor can execute virtual methods which can be overridden in the derived class. This is almost always a bad idea though. (All kinds of normal preconditions are invalid at this point. You can observe readonly variables which haven't been set yet because they'll be set in the constructor body, for example. Ick.)
To demonstrate both of these:
using System;
class BaseClass
{
public BaseClass()
{
VirtualMethod();
Console.WriteLine("BaseClass ctor body");
}
public virtual void VirtualMethod()
{
Console.WriteLine("BaseClass.VirtualMethod");
}
}
class DerivedClass : BaseClass
{
int ignored = ExecuteSomeCode();
public DerivedClass() : base()
{
Console.WriteLine("DerivedClass ctor body");
}
static int ExecuteSomeCode()
{
Console.WriteLine("Method called from initializer");
return 5;
}
public override void VirtualMethod()
{
Console.WriteLine("DerivedClass.VirtualMethod");
}
}
class Test
{
static void Main()
{
new DerivedClass();
}
}
Output:
Method called from initializer
DerivedClass.VirtualMethod
BaseClass ctor body
DerivedClass ctor body
Additionally, if your base class constructor takes a parameter, then you can execute some code in the derived class in order to provide an argument:
DerivedClass() : base(SomeStaticMethod())
All of these are fairly smelly though. What's your specific situation?
No, you can't do that. Base classes are always initialized first. However, you can do something like this:
class BaseClass
{
public BaseClass()
{
this.Initialize();
}
protected virtual void Initialize()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
}
protected override void Initialize()
{
System.Console.WriteLine("This should be shown first");
base.Initialize();
}
}
One more option is to make child class constructor as static , so that it executes first than parent class constructor. but it not preferable it violates the oop design
I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
and, my proxy resembles:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.
There is a way to create an object without calling any instance constructors.
Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.
This is how you do it:
FormatterServices.GetUninitializedObject(typeof(MyClass));
Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.
When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.
If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.
At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.
I don't believe you can get around calling the constructor. But you could do something like this:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
protected virtual void Setup()
{
}
}
public BaseClassProxy : BaseClass
{
bool _fakeOut;
protected BaseClassProxy(bool fakeOut)
{
_fakeOut = fakeOut;
Setup();
}
public override void Setup()
{
if(_fakeOut)
{
base.Setup();
}
//Your other constructor code
}
}
If what you want is to not call either of the two base class constructors, this cannot be done.
C# class constructors must call base class constructors. If you don't call one explicitly, base( ) is implied. In your example, if you do not specify which base class constructor to call, it is the same as:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
If you prefer to use the other base class constructor, you can use:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
Either way, one of the two will be called, explicitly or implicitly.
When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:
public BaseClassProxy (bool fakeOut) : base (10) {}
To call the second constructor instead of the first one
I am affraid that not base calling constructor isn't option.
I ended up doing something like this:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
This got me around some of the bad practices of the base class.
constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.
All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work. I was hoping to avoid using this in my class but here it is:
Here is my class constructor:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
OK now you were warned that it was ugly. No complaints please!
I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.
I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor. And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!
It is possible to create an object without calling the parameterless constructor (see answer above). But I use code like this to create a base class and an inherited class, in which I can choose whether to execute the base class's init.
public class MyClass_Base
{
public MyClass_Base()
{
/// Don't call the InitClass() when the object is inherited
/// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
{
this.InitClass();
}
}
protected void InitClass()
{
// The init stuff
}
}
public class MyClass : MyClass_Base
{
public MyClass(bool callBaseClassInit)
{
if(callBaseClassInit == true)
base.InitClass();
}
}
Here is my solution to the problem
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(new Child().Test);
}
public class Child : Parent {
public Child() : base(false) {
//No Parent Constructor called
}
}
public class Parent {
public int Test {get;set;}
public Parent()
{
Test = 5;
}
public Parent(bool NoBase){
//Don't do anything
}
}
}
A simple elegant solution. You can change it according to your need.
Another simple solution from me:
class parent
{
public parent()
{
//code for all children
if (this.GetType() == typeof(child1))
{
//code only for objects of class "child1"
}
else
{
//code for objects of other child classes
}
}
}
class child1 : parent
{
public child1()
{}
}
// class child2: parent ... child3 : parent ... e.t.c