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);
}
}
Related
I am encounter with a situation where I need to copy the members of base class to derived class.
I have an Instance of Base class which are returning by some other service, the same class we have used as a base class for further classes.
When we crates an object of derived class I want to assign the already created instance of base class to derived class, I know we can not assign the base class object to derived class but I am still searching any other solution.
Any one has any Idea?
Example :
public class VBase
{
public string Type {get;set;}
public string Colour {get;set;}
}
public class Car : VBase
{
public string Name {get;set;}
public int Year {get;set;}
}
// This class instance I am getting from some other source
VBase mBase= new VBase();
mBase.Type = "SUV";
mBase.Colour = "Black";
//-------------------------------------------------------
Car myCar= new Car();
myCar.Name = "AUDI";
mBase.Year = "2016";
//here I want to copy the instance of base class to derived class some thing like this or any other possible way.
myCar.base=mBase;
It is not possible in naïve way.
I'd like to recommend to define constructor or static method. I personally do not recommend to use additional libraries like AutoMapper for this job as they could require some conversion and make code cumbersome.
public class Car : VBase
{
// Method 1: define constructor.
public class Car(VBase v) {
this.Type = v.Type;
this.Colour = v.Colour;
}
// Method 2: static method.
public static Car FromVBase(VBase v){
return new Car()
{
this.Type = v.Type;
this.Colour = v.Colour;
};
}
public string Name {get;set;}
public int Year {get;set;}
}
Without using reflection, if your classes are lightweight, and wont change overtime, then you could create a public property of Base in Car:
public class Car : VBase
{
public string Name
{
get;
set;
}
public int Year
{
get;
set;
}
public VBase Base
{
set
{
base.Type = value.Type;
base.Colour = value.Colour;
}
}
}
You can then easily pass through your base class like so:
myCar.Base = mBase;
I have created a dotnetfiddle here:
dotnetfiddle for this question
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.
Though many questions on this topic exist, I am unable to find (yet) a satisfying solution:
Is it possible (and if yes, how?) to access a derived class from the base virtual method?
Let's imagine I have the following classes:
public class parent_class
{
public virtual string common_method () {
dynamic child = /* something to access the derived class */ ;
if (child == null)
return typeof(parent_class).FullName;
else
return child.GetType().FullName;
}
}
public class child_class1 : parent_class {}
public class child_class2 : parent_class {}
public class child_class3 : parent_class {}
Is it possible to execute the following code (and getting the correct result)?
parent_class p = new parent_class();
child_class1 c1 = new child_class1();
child_class2 c2 = new child_class2();
child_class3 c3 = new child_class3();
System.Console.WriteLine(p.common_method()); // result: 'parent_class'
System.Console.WriteLine(c1.common_method()); // result: 'child_class1'
System.Console.WriteLine(c2.common_method()); // result: 'child_class2'
System.Console.WriteLine(c3.common_method()); // result: 'child_class3'
EDIT: After reading the comments and replies I have to add the following points:
I have about 300 different "child classes", so overriding is not an option
I do not want to print the derived class' name - It was just an example
#Siamak Ferdos: I tried the this-keyword, but it somehow did not work as I intended.
Yes you can do it by 'this' keyword simply:
public class parent_class
{
public virtual string common_method()
{
//dynamic child = /* something to access the derived class */ ;
if (this.GetType() == typeof(parent_class))
return typeof(parent_class).FullName;
else
return this.GetType().FullName;
}
}
public class child_class1 : parent_class { }
public class child_class2 : parent_class { }
public class child_class3 : parent_class { }
If I understand your question correctly, you want to print the classes full name via a common base class method. At runtime, the actual instantiated type name is what GetType().FullName will produce, not the type of the base class.
This can be tested with a simple example:
void Main()
{
var parent = new Parent();
var child = new Child();
Console.WriteLine(parent.GetName());
Console.WriteLine(child.GetName());
}
public class Parent
{
public string GetName()
{
return this.GetType().FullName;
}
}
public class Child : Parent
{
}
Yields:
UserQuery+Parent
UserQuery+Child
Where UserQuery is the defined namespace.
There is no need for the method to be virtual or overriden in the derived class for this to work.
I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();
I have 2 classes:
public class Class1
{
private string Name1;
public Class1()
{
//How to get Name2 of the derived class?
}
}
public class Class2 : Class1
{
private string Name2 = "asd";
public Class2(){}
}
How to get Name2 of the derived class in the base constructor?
public class Class1
{
private string Name1;
public Class1()
{
class2 xxx = this as class2
if (class2 != null)
this.Name1 = xxx.Name2;
}
}
"this as class2" - is not null
This example is correct. The only thing is I don't know Derived class is Class2 or class3 or class4 .... I need universal code
You cannot (and more importantly, you should not) do that. When you are in the constructor of the base class, the subclass portion has not been initialized yet, so there is no way to get to the members of the subclass: quite simply, they do not exist yet.
Another problem is that the Name2 attribute may not be present in a subclass at all, even at the level fo the definition: I can derive Class3 from Class1, and give it Name3 attribute instead of Name2.
All this does not touch on such "insignificant" matters as breaking encapsulation: Name2 is a private member, which may be removed in the future implementations of the Class2.
The only way for the subclass to communicate things to superclass in a constructor is passing parameters. This would work:
public class Class1 {
private string Name1;
public Class1(string subclassName2)
{
// Subclass has passed its Name2 here
}
}
public class Class2: class1 {
private string Name2;
public Class2(string myName) : base(myName) {
Name2 = myName;
}
}
You can access the code in the derived class from the base class code, but only from within an object which is actually a derived class object, and then only if the methods involved are virtual methods.
If you have an object which is itself an instance of the base class, then from within that instance you cannot see derived class code from the base class .
example
public class Baseclass{
public void Foo()
{
Bar();
}
public virtual void Bar()
{
print("I'm a BaseClass");}}
public classs Derived: BaseClass{
public override void Bar()
{
print("I'm a Derived Class");}}
Main()
var b = new BaseClass();
x.Foo() // prints "I'm a BaseClass"
// This Foo() calls Bar() in base class
var d = new Derived();
d.Foo() // prints "I'm a Derived Class"
// in above, the code for Foo() (in BaseClass)
// is accessing Bar() in derived class
I think you could not because when you instantiate derived class, base class constructor is called first to initialize base class and then the derived class is initialized.Within the base class constructor there is no way to access derived class members because they are not available at that time.
You cannot do it. It strictly violates the Object Oriented Approach programming ground rules.
As each instance of Class2 will have the Name2 property. But the same cannot be guaranteed for instance of object for Class1.
It's not really clear what you're trying to achieve. It is possible to do the following, but I don't think it's good practice:
interface IHasName2
{
string Name2 { get; }
}
class Class1
{
string Name1;
public Class1()
{
var withName2 = this as IHasName2;
if (withName2 != null)
{
Name1 = withName2.Name2;
}
}
}
Then classes deriving from Class1 may implement IHasName2 if they like.
But maybe you want an abstract class to make sure derived classes specify a Name2. It could be like this:
abstract class Class1
{
string Name1;
// instance property required to be implemented by deriving classes
protected abstract string Name2 { get; }
// instance constructor
protected Class1()
{
// 'Name2' can be read already here (dangerous?)
Name1 = Name2;
}
}
Finally, consider the simple solution proposed by dasblinkenlight to have the instance constructors of Class1 take in a string parameter for the name. Deriving classes would then have to supply that name parameter when they "chain" their base class constructor.