C# Casting to the base class and using it's methods - c#

I tried casting a new variable/object to it's base class but when I debug I notice it has the class members of the derived class. So when I call an over ridden method it calls the derived class instead of the base even though the object is declared as the base.
Person person = new Student("Bill", 3.5, "chem");
Console.WriteLine(person.ToString());
....
public class Person
{
string name;
public override string ToString() => this.name + " age:" + this.age;
}
public class Student : Person
{
string major;
double GPA;
public override string ToString() => Name + " major:" + major + " GPA: " + GPA;
}
To remedy this I need to define the ToString() method in the derived class as new. But I don't understand why as I'm casting to the base so it should use the base method? Is it due to the way the compiler treats reference objects? The new object of base class still references the derived class memory instead of copying the appropriate data to it's own memory block.

Yes and that's known as Polymorphism or run time polymorphism. It's happening so cause the actual type is Student even though the declared type is person in your below code line. So the method call happens on the actual type and not on the declared type.
Person person = new Student("Bill", 3.5, "chem");

There are three keywords needed to control this behaviour with polymophism. Virtual, Override, and New. These are explained well here, and from MSDN:
Override:
The override modifier may be used on virtual methods and must be used on abstract methods. This indicates for the compiler to use the last defined implementation of a method. Even if the method is called on a reference to the base class it will use the implementation overriding it.
New:
The new modifier instructs the compiler to use your child class implementation instead of the parent class implementation. Any code that is not referencing your class but the parent class will use the parent class implementation.
An Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BindingExample
{
public class SomeBaseClass
{
public virtual string CustomString() => "From SomeBaseClass";
}
public class FirstSpecialisation : SomeBaseClass
{
public override string CustomString() => "From FirstSpecialisation";
}
public class SecondSpecialisation : SomeBaseClass
{
public new string CustomString() => "From SecondSpecialisation";
}
class Program
{
static void Main(string[] args)
{
// Base Example, as expected
SomeBaseClass a1 = new SomeBaseClass();
Console.WriteLine(a1.CustomString());
// First Example, both output the same result
FirstSpecialisation b1 = new FirstSpecialisation();
SomeBaseClass b2 = b1;
Console.WriteLine(b1.CustomString());
Console.WriteLine(b2.CustomString());
// Second Example, output different results
SecondSpecialisation c1 = new SecondSpecialisation();
SomeBaseClass c2 = c1;
Console.WriteLine(c1.CustomString());
Console.WriteLine(c2.CustomString());
Console.ReadLine();
}
}
}
Output:
From SomeBaseClass
From FirstSpecialisation
From FirstSpecialisation
From SecondSpecialisation
From SomeBaseClass
Note the above behaviour with the SecondSpecialisation class on lines 4 and 5.
This is particularly interesting in your example, because you are overriding a method with 2 depths. If you use overide twice, an unusual behaviour is evoked; the last override expressed takes precedence. Hence, you must use the new keyword.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BindingExample
{
public class SomeBaseClassA
{
public override string ToString() => "From SomeBaseClassA";
}
public class SpecialisationA : SomeBaseClassA
{
public override string ToString() => "From SpecialisationA";
}
public class SomeBaseClassB
{
public new string ToString() => "From SomeBaseClassB";
}
public class SpecialisationB : SomeBaseClassB
{
public new string ToString() => "From SpecialisationB";
}
class Program
{
static void Main(string[] args)
{
// First Example
SomeBaseClassA a1 = new SomeBaseClassA();
Console.WriteLine(a1);
SpecialisationA a2 = new SpecialisationA();
Console.WriteLine(a2);
SomeBaseClassA a3 = a2;
Console.WriteLine(a3);
// Second Example
SomeBaseClassB b1 = new SomeBaseClassB();
Console.WriteLine(b1.ToString());
SpecialisationB b2 = new SpecialisationB();
Console.WriteLine(b2.ToString());
SomeBaseClassB b3 = b2;
Console.WriteLine(b3.ToString());
Console.ReadLine();
}
}
}
Output:
From SomeBaseClassA
From SpecialisationA
From SpecialisationA
From SomeBaseClassB
From SpecialisationB
From SomeBaseClassB
I did observe when overriding the ToString method that it was called on Object. I would assume this is because the Console.WriteLine method can take an object, and because the new keyword was used on the 'ToString' methods within the specialisations, the compiler calls Object.ToString instead. This is something you may wish to be mindful of.

Related

Getting methods from base class?

I am brand new to base classes so please correct me if I am wrong or I should be doing this another way, but I have coded a simple code snippet below that explains what I want to do.
class A : B
{
private int _classId;
public A (int id) : base(id)
{
_classId = id;
}
public string GetString()
{
return "This will eventually be an important string.";
}
}
class B
{
private int _classId;
public B (int id)
{
// here I want to be able to get access to class A's methods
// such as GetString() ...
}
public void SomeMethod()
{
}
}
So what I want to do is allow B to get A's methods.
Reason for doing this?
I don't want to populate the class A because B is going to have a lot of methods so it would be cleaner to keep them in B then just get them from A in other code. Am I doing this wrong? is this not what base classes do? I simply just want to be able to still do this:
A.SomeMethodInB();
Without populating class A with junk and making it cleaner by storing it in class B
Let me summarize your question:
You want a method that is only implemented in a descendant class (A)
You want this method to be available to both the base class (B) and the descendant class (A)
You want the base class to be able to call the descendant class' implementation of the method
This is the original definition of polymorphism (lately people have been using the term much more generally) and is bread-and-butter when it comes to OOP. It is also the hardest area of OOP to grasp for newcomers.
Write a base class with a virtual method
Let us start with the base class. Notice I have changed your example slightly, for a reason I will explain in a moment.
class B
{
virtual protected string GetString()
{
return "I am a B";
}
public void DoSomethingWithGetString()
{
Console.WriteLine(GetString());
}
}
In this example, DoSomethingWithGetString calls GetString. Note that GetString is virtual. This tells the compiler that we don't want to decide where the implementation of GetString is until runtime. This means it can't be bound at compile time: instead, its location is identified by a runtime Virtual Method Table that is set up when the object is created. If this code is running as part of a instance of class B, then it will call class B's implementation of GetString. But if this code was inherited, and is actually being called by some other object that descends from class B, it will call that class' version of GetString. This is called late binding.
Write the descendant class
So now let's write class A:
class A : B
{
protected override GetString()
{
return "I am an A.";
}
}
Because A descends from B, we don't need to implement anything else. If we call A.DoSomethingWithGetString it'll actually call B's implementation because it is inherited.
Execute it
If you run this code
var a = new A();
a.DoSomethingWithGetString(); //Output = "I am an A"
...the following will happen:
An instance of A, which descends from B, is created
The VMT of A is configured so that calls to GetString are sent to A.GetString.
You call A.DoSomethingWithGetString
This call is directed to B's code base, because A doesn't implement it.
The code base in B detects that GetString is a virtual method, and calls it using the VMT.
The VMT points to A's implementation of GetString.
A.GetString is executed.
Thus you have an situation where code in class B is calling code in class A, which is what you asked for.
You can also run it this way:
B b = new A();
b.DoSomethingWithGetString(); //Output = "I am an A"
Thus you have a pointer to a B that says it's an A, because it is using a VMT set up for class A.
But I don't want any implementation in class B
Now, let's say you don't want class B to have any implementation at all for GetString, but you still want to be able to call the implementation in A. There is a way to do this using an abstract virtual method. Simply add the abstract keyword and remove the implementation:
abstract class B
{
abstract protected string GetString(); //Notice no implementation
public void DoSomethingWithGetString()
{
Console.WriteLine(GetString());
}
}
Of course, now you can't use class B by itself, because it requires an implementation of GetString that will only be present in a descendant class. So you can no longer create an instance of B directly; you have to subtype, and use the subtype.
Can't use constructor
Now, you'll notice in my example I removed your constructor calls. There is a reason for this. A constructor should not ever call a method that is defined on a descendant class. The reason: during construction, constructors are called up and down the inheritance hierarchy, starting with the base class and moving down the descendant chain. That means, when you call B's constructor, A's constructor has not been called yet. if A's constructor hasn't run yet, we can't be sure that A has been properly set up yet, and therefore it is a really bad idea to call any of its methods.
There are some workarounds for this, but that is a topic for a different question.
If the method is only defined in Class A, then there is no way to access it through Class B.
If the method exists in both Class A and Class B, then you can use virtual method and override.
Think it is better to use the names BaseClass and DerivedClass in an example. The names A and B are kind of arbitrary. Although A comes before B, the names don't imply the direction of inheritance intended.
class Program
{
static void Main(string[] args)
{
var bc = new BaseClass(3);
var dc = new DerivedClass(5);
Console.WriteLine("Base Class Method A: " + bc.MethodA());
Console.WriteLine("Derived Class Method A: " + dc.MethodA());
Console.WriteLine("Base Class Method B: " + bc.MethodB());
Console.WriteLine("Derived Class Method B: " + dc.MethodB());
Console.ReadLine();
}
}
public class BaseClass {
protected int _classId;
public BaseClass(int classId) {
_classId = classId;
}
public virtual string MethodA() {
return "Method A in base class: " + _classId.ToString();
}
public string MethodB()
{
return "I am a method B in the base class: " + _classId.ToString();
}
}
public class DerivedClass : BaseClass {
public DerivedClass(int classId)
: base(classId)
{
}
public override string MethodA() {
return "Method A in derived class: " + _classId.ToString();
}
}
There are two ways you can go about this. Let me first set out an example.
Here we have the base class that contains a method:
public class Base
{
public void BaseMethod()
{
// Some method.
}
}
Here is the derived class, where we want to call the method:
public class DerivedClass : BaseClass
{
// We want to use BaseMethod() here.
}
In order to call a method from the base class, we use the base keyword.
public class DerivedClass : BaseClass
{
base.BaseMethod();
}
This is fine if you want to just call the base method. However, if we want to change the method and define it with a different function, we have to declare it as virtual in the base class, as so:
public class Base
{
public virtual void BaseMethod()
{
// Some method.
}
}
In the derived class, we can now use the keyword override to override the virtual method of the base class, which redefines it to do something else:
public class DerivedClass : BaseClass
{
public override void BaseMethod()
{
// Some new function.
}
}

virtual and override how to use those?

hello i wrote two simple classes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kus
{
class Program : Class1
{
public Program()
{}
public override void findtheflyingdistance(out int x)
{ x=0;
Random r = new Random();
for (int i = 0; i < 100; i++)
{
int z = r.Next(100, 500);
x += x + z;
}
Console.WriteLine("Kuş" + x);
}
static void Main(string[] args)
{
int x;
Program pg = new Program();
pg.findtheflyingdistance(out x);
Class1 C1 = pg;
C1.findtheflyingdistance(out x);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kus
{
class Class1
{
public Class1(){}
public virtual void findtheflyingdistance(out int x)
{ x=0;
int z=200;
x += x + z;
Console.WriteLine("Leylek" +x);
}
}
}
as i understand override method override the virtual method. When i create two instance in the main Program class. findtheflyingdistance(out int x) in Program class worked for two instance but when i did method findtheflyingdistance(out int x) virtual in two clasess. Each instance work with own classes. So i dont understand the logic behind the scene. Why do we write virtual methods? if we want to override a method we can do override and non-virtual method that will be overriden already.
Virtual allows you to override a method which is defined in the base class. In other words, it extends the implementation of the method in the derived class.
this would be an interesting read.
this stackoverflow answer also gives a short example, which i have copied below for handiness:
The virtual keyword is used to modify a method, property, indexer or
event declaration, and allow it to be overridden in a derived class.
For example, this method can be overridden by any class that inherits
it: Use the new modifier to explicitly hide a member inherited from a
base class. To hide an inherited member, declare it in the derived
class using the same name, and modify it with the new modifier.
This is all to do with polymorphism. When a virtual method is called
on a reference, the actual type of the object that the reference
refers to is used to decide which method implementation to use. When a
method of a base class is overridden in a derived class, the version
in the derived class is used, even if the calling code didn't "know"
that the object was an instance of the derived class. For instance:
public class Base { public virtual void SomeMethod() { } }
public class Derived : Base { public override void SomeMethod() { } }
...
Base b = new Derived();
b.SomeMethod();
will end up calling
Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the
derived class doesn't override the method in the base class, it merely
hides it. In that case, code like this:
public class Base { public virtual void SomeOtherMethod() { } }
public class Derived : Base { public new void SomeOtherMethod() { } }
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call
Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're
effectively two entirely separate methods which happen to have the
same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is
the same as if you specified new, but you'll also get a compiler
warning (as you may not be aware that you're hiding a method in the
base class method, or indeed you may have wanted to override it, and
merely forgot to include the keyword).
An overriding property declaration may include the sealed modifier.
Use of this modifier prevents a derived class from further overriding
the property. The accessors of a sealed property are also sealed.

How to not hide base class members while inheriting in c#

I am not getting the base class member in this code. Please suggest. I'm a rookie here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CaseStudy1
{
class base1
{
protected string name = "";
public base1() {}
public base1(string dad)
{
this.name = dad;
}
}
class child1 : base1
{
private string name = "";
public child1()
{
this.name = base.name;
}
public void show()
{
base1 b1 = new base1("Daddy");
Console.WriteLine("base name"+base.name);
Console.WriteLine("child's name" + name);
}
public static void Main(string[] args)
{
child1 c1 = new child1();
c1.show();
Console.ReadLine();
}
}
In C# Inheritance, what you have as a "child" class is not really a child (being owned by the base) but a more specific version of the base (as like a football being a specific kind of ball). The base class and the inherited class are the same actual object. Therefore, the new keyword is out of place, since what you want is the base class's name, not a new base object all together. By using the same name for a property in both the base and the inherited class, you are "hiding" the property in the base, since a single object can't have the same property twice (in your example, your object can't have 2 different name. If what you want to do is have the inherited class know the name of the base, they need to be different properties.
The best way to think of it is that if you use new to create an object, that object will have every property and method of itself and any class above it in the class tree, so a child1 object would have the child1 and the base1 properties and methods, but a new base1 object only has the base1 properties and methods.
As a side effect, a child1 object can be used in any statement that requires a base1 object, since a child1 object is a base1 object.
Here within the Show method you create the new instance of base1 class.So you cannot read from setted value from using base.name.because of b1 is new instance.
You can use as follows.
class base1
{
protected string name { get; set; }
public base1() { }
}
class child1 : base1
{
private string name = "";
public void show()
{
base.name = "Daddy";
this.name = base.name;
Console.WriteLine("base name" + base.name);
Console.WriteLine("child's name" + name);
}
}

Calling a method of a class through the interface implemented by the base class c#

I have this code but I just can't understand it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1 {
interface IStoreable {
void Read();
void Write();
}
class Person : IStoreable {
public virtual void Read() { Console.WriteLine("Person.Read()"); }
public void Write() { Console.WriteLine("Person.Write()"); }
}
class Student : Person {
public override void Read() { Console.WriteLine("Student.Read()"); }
public new void Write() { Console.WriteLine("Student.Write()"); }
}
class Demo {
static void Main(string[] args) {
Person s1 = new Student();
IStoreable isStudent1 = s1 as IStoreable;
// 1
Console.WriteLine("// 1");
isStudent1.Read();
isStudent1.Write();
Student s2 = new Student();
IStoreable isStudent2 = s2 as IStoreable;
// 2
Console.WriteLine("// 2");
isStudent2.Read();
isStudent2.Write();
Console.ReadKey();
}
}
}
I thought Student.Write() would be called in both cases, so I was puzzled by what I got:
// 1
Student.Read()
Person.Write()
// 2
Student.Read()
Person.Write()
Why is Person.Write() called instead of 'Student.Write()`?
The new keyword indicates that you do not intend to override the base class's Write() method (you can't anyway, since Person's Write() method isn't marked virtual). Since you're calling it via IStoreable, there's nothing about the IStoreable interface that links it to the Student class. Since Write() is not marked virtual, polymorphism for this function doesn't apply.
Student as an IStoreable cannot see the Student.Write method since it is not overriden from the base class Person. Why is it not marked virtual, and why have you used the new keyword to hide the base class's implementation?
Make the person's write method Virtual. When you mark it new it does not act as an inherited method. When you mark the method virtual that means you provide an implementation and can override it by a child class. Abstract requires you implementat a method (just a little more fyi).
class Person : IStoreable {
public virtual void Read() { Console.WriteLine("Person.Read()"); }
public virtual void Write() { Console.WriteLine("Person.Write()"); }
}
class Student : Person {
public override void Read() { Console.WriteLine("Student.Read()"); }
public override void Write() { Console.WriteLine("Student.Write()"); }
"When used as a modifier, the new keyword explicitly hides a member inherited from a base class" via

Is there any other way to implement Overriding (not virtual and override) in C# / .NET?

Could anyone tell me is there any other way a method can be overridden without using virtual/abstract/override in C#/.NET, Please provide me with an example.Please provide with an example...
(what i am thinking is Extension methods am i correct.....)
No, there is no other way. You can hide an existing method with new if the base method is not marked as virtual, however it does not have the same effect (there is no polymorphism - the call will be dispatched based on the variable type, not on the actual object type).
Extension will not work in this case. Objects own properties and methods take precedence. However you can overload a method using extensions.
You can override methods defined in the extensions, by keeping your extensions closer in the namespace to the place where you are going to use it.
Example:
namespace ConsoleApplication2
{
using System;
using ConsoleApplication3;
internal class Program
{
private static void Main(string[] args)
{
ThirdPartyClass t = new ThirdPartyClass();
Console.WriteLine(t.Fun("hh"));
Console.WriteLine(t.Fun(1));
}
}
public static class LocalExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "Local" + val;
}
public static string Fun(this ThirdPartyClass test, string val)
{
return "Local" + val;
}
}
}
namespace ConsoleApplication3
{
public class ThirdPartyClass
{
public virtual string Fun(string val)
{
return "ThirdParty" + val.ToUpper();
}
}
public static class ThripartyExtension
{
public static string Fun(this ThirdPartyClass test, int val)
{
return "ThirdParty" + val;
}
}
}
You can use the "new" keyword on your method to "hide" a method that was not declared as abstract/virtual, however if the method is called from a variable type-casted as the base class, it won't call your new method. This is the similar to overriding.
Example:
public class A
{
public string GetName() { return "A"; }
}
public class B : A
{
// this method overrides the original
public new string GetName() { return "B"; }
}
Extension methods allow you to add new methods to any class even if you don't have their source code or they're sealed. This is not the same as overriding
public sealed class A // this could even be from a dll that you don't have source code to
{
}
public static class AExtensionMethods
{
// when AdditionalMethod gets called, it's as if it's from inside the class, and it
// has a reference to the object it was called from. However, you can't access
// private/protected fields.
public static string AdditionalMethod(this A instance)
{
return "asdf";
}
}
Another option is to use interfaces so that you can have two completely different objects that both have the same method, but when called from a variable type-casted as the interface, it looks similar to overriding.
You could also use a form of Proxy Mocking framework like Microsoft Moles, or CastleWindsor -> They have a way of instantiating a "proxy" object that has the same interface as the real object, but can provide a different implementation for each method.

Categories

Resources