I have a desing question. Lets say I have a base class, and many derived classes.
class MyBase
{
MyBase()
{
Record();
}
void Record()
{
/// this line is able to handle every object
Recorder.Process(this);
}
}
class DerivedA : MyBase
{
public int SpecialPropertyOfA { get; set; }
DerivedA(int specialPropertyOfA)
{
SpecialPropertyOfA = specialPropertyOfA;
}
}
class DerivedB : MyBase
{
public string SpecialPropertyOfB { get; set; }
DerivedA(string specialPropertyOfB)
{
SpecialPropertyOfB = specialPropertyOfB;
}
}
As you may deduce, I want to record derived classes with all their properties set. But the above example cannot record the special properties of derived classes since they are not set when the Record method called.
One way to overcome this is to make Record method protected and call it as the last line of derived classes constructors. But this violates my base principals(every derived class should be recorded right after initialization). I want to make this mandotory by design.
Any ways to handle this?
Take a look again at what you're trying to do.
Remember that base class constructor is called before the derived class's constructor.
MyBase()
{
Record();
}
void Record()
{
Recorder.Process(this); // <-- What is "this" ?
}
What would be the value of this at this point?
The instance has not been constructed yet, the derived class's constructor hasn't event been called so there's no reference to this, hence, you can't use it here.
You'll have to call this method after the instance has been fully constructed.
A way to overcome this is using a factory method:
public static class MyBaseFactory
{
public static MyBase CreateDerivedA()
{
int specialPropertyOfA = // ...
MyBase instance = new DerivedA(specialPropertyOfA);
Recorder.Process(instance);
return instance;
}
public static MyBase CreateDerivedB()
{
string specialPropertyOfB = // ...
MyBase instance = new DerivedB(specialPropertyOfA);
Recorder.Process(instance);
return instance;
}
}
Related
I have a question regards chaining constructors I read some question on StackOverflow and some c# articles but I cannot understand the topic fully. So I have a BaseClass that is inherited by DerivedClass. In the DerivedClass, I have no argument constructor but it's calling the base constructor using: base() and it also passing a value. Is this the primary purpose of the base keyword used in the constructor to pass a value to the inherited class from the derived one or is something more out there. And also in the derived class, we have a second constructor that takes 1 parameter and its using: this(). I can't understand why when I remove: this() from this constructor "VS" tells me "There is no argument given that corresponds to the required formal parameter "i" of BaseClass.BaseClass(int) ? Why I can't just have one argument constructor in the DerivedClass without using this()?
public class BaseClass
{
protected int _Num;
public BaseClass(int i)
{
_Num = i;
}
public int Num { get => this._Num ; set => _Num = value; }
}
public class DerivedClassA : BaseClass
{
private string _Name;
private int _AnotherValue;
public string Name { get => this._Name ; set => this._Name = value; }
public int AnotherValue { get => this._AnotherValue; set => this._AnotherValue = value; }
public DerivedClassA() : base(123)
{
_Name = "testing";
}
public DerivedClassA(int param2) : this() <-- Why i can't compile the program without the this() keyword here ?
{
AnotherValue = param2;
}
}
public class Program
{
public static void Main(string[] args)
{
DerivedClassA objA = new DerivedClassA(5);
}
}
I can't find a duplicate that exactly matches, so I'll provide an answer.
Imagine these classes:
public class Base
{
public Base()
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
When you initialize a derived class, you have to first initialize the base. In our example above, the Base class has a parameterless constructor, so the derived class can implicitly call it. If we add a base second constructor, this logic remains true, and the parameterless constructor will still be implicitly called:
public class Base
{
public Base()
{
}
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
But if we take away the parameterless constructor, Derived must now call the base constructor explicitly:
public class Base
{
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived() : base(1)
{
}
}
Try it online
So what happens if we add an extra derived class constructor? Well, that also has to call the base class (either directly, or indirectly):
public class Base
{
public Base(int a)
{
// this method body is executed first
}
}
public class DerivedA : Base
{
public DerivedA(string name, int val) : base(val)
{
// this method body is executed second (last if you used this constructor, e.g. new DerivedA("hello", 1) )
}
public DerivedA() : this("test", 5) // this will call the constructor above, which will first call base. So the final chain is: base, constructor above, this constructor
{
// this method body is executed third (last if you used this constructor, e.g. new DerivedA() )
}
}
public class DerivedB : Base
{
public DerivedB(string name, int val) : base(val)
{
}
public DerivedB() : base(5) // this will call the base constructor, and then this constructor. The constructor above will not be used.
{
}
}
Try it online
Note that all classes have a parameterless constructor when no other constructor is defined, so the following two examples are equivalent:
public class BaseA
{
}
public class BaseB
{
public BaseB()
{
}
}
You'll note that SharpLab shows the compiler removed the empty constructor from BaseB() since it's superfluous.
Finally, a derived class without an explicitly defined constructor, will still call the base class constructor implicitly:
public class Base
{
public Base()
{
// this method body is executed first
Console.WriteLine("Base constructor");
}
}
public class Derived : Base
{
}
Try it online
So to summarise: unless your base class has a parameterless constructor, your derived class constructors have to either call a base constructor directly, or indirectly through another derived class constructor. Obviously you only need to call a single base constructor method, as with any other class instantiation. You don't need matching derived methods for each base method, so long as you can construct the base with the values you do have.
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();
}
}
I have some doubts in my below codes,
public class ClassA: BaseClass
{
public ClassA(UIElement element)
: base(element)
{
}
}
public class ClassA: BaseClass
{
public ClassA(UIElement element)
{
}
}
What is the difference between the above codes?
Doubts:
1.It is necessary to call base constructor
2.What is the use to Call the base constructor
3.If we didn't call base constructor it calls implicitly.
Any one please provide suggestion for this.
the first one instructs to use the BaseClass(UIElement) constructor, while the other one will use BaseClass() to be initialised instead.
To your questions; it all depends on if it makes sense to initiase BaseClass with the passed element or not.
Not always, if you don't specify anything then base() will be called
base() as you already did
Yes
In each case a base constructor is called, just implicitly and using the default in the latter case - in the first case it's using an explicit base constructor which accepts an argument. If no default parameterless constructor existed on the base class then an error would be encountered if it wasn't explicitly called by the user in order to provide the required input.
So, it's only necessary to call if you need to pass input to a specific constructor or a default public constructor is not defined.
1-3. no it's not necessary it call it automagically if the base calss contain a constructor without parameter
2. you use base when you inherit from another class, the part you inherited need to be constructed too so you have to call the base constructor
Please note 2 more things using chained contructors
The Base Contructor is always called before the actual constructor.
The constructors can have different accessabilities like private or public. You cannot chain every constructor from the base to the derived class.
The first one passes a parameter to the base constructor, while the second one uses the default (parameterless constructor).
public class Human
{
public string Name { get; set; }
public Human()
{
Name = "No name";
}
public Human(string name)
{
Name = name + " Jr.";
}
}
public class Male : Human
{
public Male() {}
public Male(string name) : base(name) {}
}
public class Female : Human
{
public Female() { Name = "Girl"; }
}
var unnamedHuman = new Human();
//unnamedHuman.Name == "No name"
var namedHuman = new Human("Jon");
//namedHuman.Name == "Jon"
var unnamedMale = new Male();
// unnamedMale.Name == "No name"
var namedMale = new Male("Chris");
// namedMale.Name == "Chris Jr";
var unnamedFemale = new Female()
// unnamedFemale.Name == "Girl"
The logic:
When you initialize a child class (by calling their ctor), first its base class constructors are called in order (top-down), the final one would be your child class' constructor you invoked.
By default, the default parameterless contructor is used but you can specify and pass arguments to the base constructor by using base(parameter1, p2).
If your BaseClass looked like:
public class BaseClass
{
private readonly _element;
public BaseClass(UIElement element)
{
_element = element;
}
}
Then you would absolutely have to call the base constructor, because it's the only constructor that BaseClass has.
If it looked like this:
public class BaseClass
{
private readonly _element;
public BaseClass()
{
_element = default(UIElement);
}
public BaseClass(UIElement element)
{
_element = element;
}
}
Then you would absolutely have to call the base constructor if you wanted to set the element, as it can only be set in the constuctor.
If it looked like this:
public class BaseClass
{
private _element;
public BaseClass()
{
_element = default(UIElement);
}
public BaseClass(UIElement element)
{
_element = element;
}
public UIElement Element
{
get{ return _element; }
set{ _element = value; }
}
}
Then you could choose between:
public class ClassA: BaseClass
{
public ClassA(UIElement element)
: base(element)
{
}
}
public class ClassA: BaseClass
{
public ClassA(UIElement element)
{
Element = element;
}
}
However, the former is clearer and doesn't have a period where Element returns the default (null) during the overall construction.
In all, consider that ClassA is a type of BaseClass. In creating a sensible instance of ClassA you have to do everything entailed in setting up a sensible instance of BaseClass. It is the job of the constructor to make sure this happens. Lean toward calling the base constructor as much as is meaningful.
I need a method that creates an empty clone of an object in a base class? For instance:
public class ChildClass : ParentClass
{
public ChildClass()
{
}
}
public class ParentClass
{
public SomeMethod()
{
// I want to create an instance of the ChildClass here
}
}
Up until now, we have an abstract method defined in the parent class. And, all of the child classes implement them. But, the implementation is the same for all, just a different type.
public class ChildClass : ParentClass
{
public ChildClass()
{
}
public ParentClass CreateEmpty()
{
return new ChildClass();
}
}
public class ParentClass
{
public SomeMethod()
{
// I want to create an instance of the ChildClass here
ParentClass empty = CreateEmpty();
}
public abstract ParentClass CreateEmpty();
}
Is there any way to do this from the parent class so that I don't have to keep implementing the same logic for each different child class? Note that there may be more levels of inheritance (i.e. ChildChildClass : ChildClass : ParentClass).
If using reflection isn't a problem to you, you could do it using Activator class:
//In parent class
public ParentClass CreateEmpty()
{
return (ParentClass)Activator.CreateInstance(this.GetType());
}
This will return empty object of the type you want. Notice that this method does not need to be virtual.
On the other hand, I think that your current approach is perfectly fine, few more lines of code aren't so bad.
You can make a deep clone of the object using the binary serializer.
EDIT: Just noticed the word "empty" next to clone (which I thought was an oxymoron). Leaving this response up anyhow hoping it will help others that find this question because they are looking to do a regular clone.
This is somewhat experimental. I don't know whether this will lead to a cyclic dependency. Haven't touched C# for some months.
public class ParentClass<T> where T : ParentClass<T>, new() { // fixed
public ParentClass() {
var x = new T(); // fixed, was T.new()
}
}
public class ChildClass : ParentClass<ChildClass> {
public ChildClass() { }
}
Otherwise go for the ReflectionCode by Ravadre.
I'm using the following pattern.
Pros:
This pattern secure the type-safety of cloning in private and public sides of classes.
The output class will be always correct.
You never forgot override the "clone" method. The "MyDerivedClass" never returns another class than the "MyDerivedClass".
Cons:
For one class, you need create one interface and two classes (prototype and final)
Sample:
// Common interface for cloneable classes.
public interface IPrototype : ICloneable {
new IPrototype Clone();
}
// Generic interface for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public interface IPrototype<TFinal> where TFinal : IPrototype<TFinal> {
new TFinal Clone();
}
// Base class for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public abstract class PrototypeBase<TFinal> : IPrototype<TFinal> where TFinal : PrototypeBase<TFinal> {
public TFinal Clone() {
TFinal ret = this.CreateCloneInstance();
if ( null == ret ) {
throw new InvalidOperationException( "Clone instance was not created." );
}
this.FillCloneInstance( ret );
return ret;
}
// If overriden, creates new cloned instance
protected abstract TFinal CreateCloneInstance();
// If overriden, fill clone instance with correct values.
protected abstract void FillCloneInstance( TFinal clone );
IPrototype IPrototype.Clone() { return this.Clone(); }
object ICloneable.Clone() { return this.Clone(); }
}
// Common interface for standalone class.
public interface IMyStandaloneClass : IPrototype<IMyStandaloneClass> {
string SomeText{get;set;}
string SomeNumber{get;set;}
}
// The prototype class contains all functionality exception the clone instance creation.
public abstract class MyStandaloneClassPrototype<TFinal> : PrototypeBase<TFinal>, IMyStandaloneClass where TFinal : MyStandaloneClassPrototype<TFinal> {
public string SomeText {get; set;}
public int SomeNumber {get; set}
protected override FillCloneInstance( TFinal clone ) {
// Now fill clone with values
clone.SomeText = this.SomeText;
clone.SomeNumber = this.SomeNumber;
}
}
// The sealed clas contains only functionality for clone instance creation.
public sealed class MyStandaloneClass : MyStandaloneClassPrototype<MyStandaloneClass> {
protected override MyStandaloneClass CreateCloneInstance() {
return new MyStandaloneClass();
}
}
public interface IMyExtendedStandaloneClass : IMyStandaloneClass, IPrototype<IMyExtendedStandaloneClass> {
DateTime SomeTime {get; set;}
}
// The extended prototype of MyStandaloneClassPrototype<TFinal>.
public abstract class MyExtendedStandaloneClassPrototype<TFinal> : MyStandaloneClassPrototype<TFinal> where TFinal : MyExtendedStandaloneClassPrototype<TFinal> {
public DateTime SomeTime {get; set;}
protected override FillCloneInstance( TFinal clone ) {
// at first, fill the base class members
base.FillCloneInstance( clone );
// Now fill clone with values
clone.SomeTime = this.SomeTime;
}
}
public sealed class MyExtendedStandaloneClass : MyExtendedStandaloneClassPrototype<TFinal> {
protected override MyExtendedStandaloneClass CreateCloneInstance() {
return new MyExtendedStandaloneClass
}
}
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