C# language - usage of "this" keyword [duplicate] - c#

I was looking at sample code from MSDN just now and came accross:
namespace IListSourceCS
{
public class Employee : BusinessObjectBase
{
private string _id;
private string _name;
private Decimal parkingId;
public Employee() : this(string.Empty, 0) {} // <<--- WHAT IS THIS???
public Employee(string name) : this(name, 0) {}

It calls the other constructor in that class with that signature. Its a way of implementing the constructor in terms of other constructors. base can also be used to call the base class constructor. You have to have a constructor of the signature that matches this for it to work.

this lets you call another constructor of Employee (current) class with (string, int) parameters.
This is a technique to initialize an object known as Constructor Chaining

This sample might help some of the different derivations... The first obviously has two constructor methods when an instance is created... such as
FirstClass oTest1 = new FirstClass();
or
FirstClass oTest1b = new FirstClass(2345);
The SECOND class is derived from FirstClass. notice it too has multiple constructors, but one is of two parameters... The two-parameter signature makes a call to the "this()" constructor (of the second class)... Which in-turn calls the BASE CLASS (FirstClass) constructor with the integer parameter...
So, when creating classes derived from others, you can refer to its OWN class constructor method, OR its base class... Similarly in code if you OVERRIDE a method, you can do something IN ADDITION to the BASE() method...
Yes, more than you may have been interested in, but maybe this clarification can help others too...
public class FirstClass
{
int SomeValue;
public FirstClass()
{ }
public FirstClass( int SomeDefaultValue )
{
SomeValue = SomeDefaultValue;
}
}
public class SecondClass : FirstClass
{
int AnotherValue;
string Test;
public SecondClass() : base( 123 )
{ Test = "testing"; }
public SecondClass( int ParmValue1, int ParmValue2 ) : this()
{
AnotherValue = ParmValue2;
}
}

A constructor is a special method/function that is ran to initialize the object created based on the class. This is where you run initialization things, as setting default values, initializes members in all ways.
"this" is a special word which points so the very own object you're in. See it as the objects refereence within the object itself used to access internal methods and members.
Check out the following links :
C# When To Use “This” Keyword
When do you use the “this” keyword?

Related

C# What does : this() mean after a constructor of struct [duplicate]

This question already has answers here:
what is 'this' constructor, what is it for
(4 answers)
Closed 6 years ago.
Could you answer, what does : this() mean after a constructor of struct?
public struct BaseProject
{
public BaseProject(string project)
: this()
{
this.Project = project;
}
public string Project { get; private set; }
}
What does : this() mean after a constructor of struct?
The this keyword in C# refers to the current instance of the class and is also used as a modifier of the first parameter of an extension method.
As it pertains to a struct and the constructor of a struct, it actually is meaningless and does nothing. In C# a struct doesn't have a parameterless constructor. They are very similar to class constructors but differ in the following ways:
Structs cannot contain explicit parameterless constructors. Struct members are automatically initialized to their default values.
A struct cannot have an initializer in the form: base (argument-list).
As such, the : this() after the struct constructor does nothing and is redundant - it can be removed with no issues whatsoever. However, in the context of a struct constructor, the this keyword works as expected.
Classes
When used in after a constructor, it invokes another constructor in the same class first - in this specific situation the parameterless constructor. This can be used to initialize other various parts of an object instance as they are invoked first.
Constructors
Read "using constructors" on MSDN for more details.
Consider the following:
public class FooBar
{
public int Number { get; }
public string Name { get; }
public FooBar()
{
Number = 10;
Name = "Pickles";
}
public FooBar(int number) : this()
{
Number = number;
}
public FooBar(int number, string name) : this(number)
{
Name = name;
}
}
var fooBar1 = new FooBar();
var fooBar2 = new FooBar(20);
var fooBar3 = new FooBar(77, "Stackoverflow");
// The following would be true
// fooBar1.Number == 10 and fooBar1.Name == "Pickles"
// fooBar2.Number == 20 and fooBar2.Name == "Pickles"
// fooBar3.Number == 77 and fooBar2.Name == "Stackoverflow"
The this keyword in the context of a constructor can also be used (as shown above) to call into parameterized constructors as well. If you were to inherit then you could call into default or parameterized constructors of the base class using the base keyword.
A constructor can invoke another constructor in the same object by
using the this keyword.
From Using Constructors (C# Programming Guide)
So in your example, when the constructor that takes a string is called, the parameterless constructor is (implicitly) called first, followed by the method body of the constructor that takes a string being executed.
It means it's calling the parameterless constructor of the type.

Calling Known Property from Unknown Class

I have a BaseClass from which I have derived multiple other Classes using Inheritance.
Elsewhere I want to be able to retrieve Properties from anyone of these inherited classes even though the type of Class isn't known until Runtime.
For example lets say I have two classes derived from BaseClass
FirstClass : BaseClass
SecondClass : BaseClass
My BaseClass has a property called ID which is an int (amongst many others)
At runtime my app will receive 'either' a FirstClass object or a SecondClass object, but either way I need to retrieve the ID property.
public int MyMethod(object unknownClass)
{
int myID = unknownClass.ID;
return myID //...does not compile
}
public int MyMethod(object unknownClass)
{
BaseClass tryCasting = (BaseClass)unknownClass;
int myID = tryCasting.ID;
return myID //...does not compile either
}
I'm not sure what else to try.
How can I get a Property which I know exists without knowing the Object type first?
Don't use object and use BaseClass:
public int MyMethod(BaseClass unknownClass)
{
int myID = unknownClass.ID;
return myID;
}
See the answer from Darren Davies for your specific case of ID. The approaches in this answer are useful when the property is defined in the derived classes, not the base class.
Use dynamic instead of object. That will use the runtime to retrieve the actual object type.
public int MyMethod(dynamic unknownClass)
{
int myID = (int)unknownClass.ID;
return myID;
}
Alternatively, you can use Reflection to retrieve the property value:
var myID = (int)unknownClass.GetType().GetProperty("ID").GetValue(unknownClass);
Polymorfism is the answer. You should know that when you create a class derived from another, the derived class acquires inmediately the properties from the base class. Thus, if you don't redefine the method (override), when you call the method MyMethod on a derived class it will
always call the base method. So the next code should work well :
BaseClass {
private : int id ;
public : int getId { return id ; }
} ;
FirstClass : BaseClass { DO NOT OVERRIDE getID ...} ;
int main (void) {
BaseClass base ;
FirstClass first ;
base = first ;
base.getId() ; //Gets the id of first.
}
What does this program? When you assign first to base you upcast first type to BaseClass. Then when you get to the execution of base.getId() the program lookups if
there is a redefinition (overriding) of this method in FirstClass, if there isn't it calls the base method.
Hope that you find this information useful. You should read the first chapters of "Thinking in C++" of Bruce Eckels, it's a good introduction to Object Oriented Programming.

Parameterized abstract class constructor

I have a class like below
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public abstract void computeA();
};
Is it mandatory for the derived class to supply the parameters for the base/abstract class constructor? Is there any way to initialize the derived class without supplying the parameters?
Thanks in advance.
Yes, you have to supply an argument to the base class constructor.
Of course, the derived class may have a parameterless constructor - it can call the base class constructor any way it wants. For example:
public class Foo : ABC
{
// Always pass 123 to the base class constructor
public Foo() : base(123)
{
}
}
So you don't necessarily need to pass any information to the derived class constructor, but the derived class constructor must pass information to the base class constructor, if that only exposes a parameterized constructor.
(Note that in real code Foo would also have to override computeA(), but that's irrelevant to the constructor part of the question, so I left it out of the sample.)
You can create a default constructor in a derived class that does not need parameters and the derived class will supply default values, but you cannot remove the requirement entirely. It is a manadatory condition of the base class to have some sort of value.
public MyDerivedClass : ABC
{
public MyDerivedClass()
: base(123) // hard wired default value for the base class
{
// Other things the constructor needs to do.
}
public override void computeA()
{
// Concrete definition for this method.
}
}
Add a default constructor to the base class and call the other constructor providing an initial values for its parameters:
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public ABC() : this(0) {}
}
It doesn't have much to do with the fact that the base class is abstract.
Because you've declared a public constructor that has 1 parameter, the compiler removes the basic empty constructor.
So, if you want to create an instance of that class, you have to pass a parameter.
When you derive from such a class, a parameter must be passed to the base class for it o construct.

How can I tell the inheriting class to not call its base class' parameter-less constructor?

I was surprised to find out that the parameter-less constructor of my base class is called any time I call any constructor in a derived class. I thought that is what : base() was for, to explicitly call the base constructor if and when I want to.
How can I prevent the base constructor from being called when I instantiate a derived class?
using System;
namespace TestConstru22323
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer("Jim", "Smith");
Customer c = new Customer();
Console.WriteLine(customer.Display());
Console.ReadLine();
}
}
public class Person
{
public Person()
{
Console.WriteLine("I don't always want this constructor to be called. I want to call it explicitly.");
}
}
public class Customer : Person
{
private string _firstName;
private string _lastName;
//public Customer(string firstName, string lastName): base() //this explicitly calls base empty constructor
public Customer(string firstName, string lastName) //but this calls it anyway, why?
{
_firstName = firstName;
_lastName = lastName;
}
public string Display()
{
return String.Format("{0}, {1}", _lastName, _firstName);
}
}
}
The only way is to explicitly tell it which other base ctor you want it to call; which of course means you must choose some base ctor to call.
You can't have it call no base ctor at all - conceptually, constructing a Customer is done by first constructing a Person, and then doing Customer specific construction on top of it. For example, suppose Person had private fields - how would these be correctly constructed if construction of a Customer was allowed to not first construct a Person?
In .NET, every object constructor in an object hierarchy will be called regardless if you call :base() or not.
:base() is implicitly called if you don't explicitly call it.
:base() can be used if you want to call a different contructor on a parent object rather than the default constructor.
If you have code in the parent constructor that should not be called everytime, it may be better to move that code to it's own method that will need to be called explicitly after the object is constructed. Or, create a parameterized constructor on the parent object and use the parameter to determine if the code should be executed or not.
For example:
:base(true) - This executes your code.
:base(false) - This does not execute your code.
As others have pointed out, a derived instance must call call one of its base class' constructors.
If you want to control the execution of a base class' initialization logic, remove its default constructor and replace it with something like this:
public class Base {
// Base has no default constructor
public Base(bool initialize) {
if (initialize) {
// ... logic here
}
}
}
And the derived constructors look like this:
// Derived1 executes the initialization logic
public Derived1(): base(true) {}
// Derived2 does not
public Derived2(): base(false) {}
You could make the default base constructor protected, then have only non-default constructors for the base and its child.
edit
You could give the base a protected constructor with a different signature (such as a protected enum type), and put your initialization code in there, while the default constructor, also protected, does not particular initialization.
Your requirement to only need to call the constructor for some derived objects is not in line with the object-oriented principles. If it's a Person, then it needs to be constructed as such.
If you need shared initialization for some objects, then you should consider creating an Initialize method or adding a parameterized constructor that will be called by the specific derived objects.
The parameterized constructor approach feels a little awkward:
public abstract class Person
{
protected Person()
{
}
protected Person( bool initialize )
{
if (initialize)
{
Initialize();
}
}
// ...
}
public class Customer : Person
{
public Customer(string firstName, string lastName)
{
// ...
}
}
public class Employee : Person
{
public Customer(string firstName, string lastName) : base(true)
{
// ...
}
}
When you instantiate a class all the classes in the inheritance hierarchy are instantiated starting from the topmost Parent to the lowermost child, stopping at the type you instantiated. So if you instantiate System.Text.StringBuilder(), first you call the default constructor of System.Object, then StringBuilder(). You can use the base keyword to call a different constructor (one with equal or fewer params), but not more params. If you do not specify base, the default constructor is called, thus the reason this is happening to you. You can also use the base keyword within the context of an instance method to call base implementations, such as in the case of the decorator pattern. If you do not want to call the base class private constructors then you should set the children with private default constructors and also explicitly call base(params) on your other constructors.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class ProcessCaller
{
static void Main()
{
MyDerived md1 = new MyDerived(1);
object o = new System.Text.StringBuilder();//This will implicitly instantiate the classes in the inheritance hierarchy: object, then stringbuilder
}
}
public class MyBase
{
int num;
public MyBase()
{
Console.WriteLine("in MyBase()");
}
public MyBase(int i )
{
num = i;
Console.WriteLine("in MyBase(int i)");
}
public virtual int GetNum()
{
return num;
}
}
public class MyDerived: MyBase
{
//set private constructor. base(i) here makes no sense cause you have no params
private MyDerived()
{
}
// Without specifying base(i), this constructor would call MyBase.MyBase()
public MyDerived(int i) : base(i)
{
}
public override int GetNum()
{
return base.GetNum();//here we use base within an instance method to call the base class implementation.
}
}
}
One way would be to make your base default constructor private, but that only works if you make a helper constructor in the base class that calls the private one when you need it explicitly.
class Base
{
private Base() { ... special default base logic ... }
protected Base(... params ...) : this() { ... exposed base that calls private cons ... }
protected Base(... other params ...) /* no default call */ { ... exposed cons that doesnt call default ...}
}
class DerivedNoCall
{
public DerivedNoCall() : base(... other params ...) {} //<-- will NOT call default base
}
class DerivedDoCall
{
public DerivedDoCall() : base(... params ...) {} //<-- WILL call default base cons indirectly
}
This is really contrived, and #aakashm has the best answer.

How can I prevent a base constructor from being called by an inheritor in C#?

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

Categories

Resources