C#, access child properties from parent reference? - c#

public void GetProps(Parent p){
// want to access lots of child properties here
string childProp1 = p.prop1;
bool childProp2 = p.prop2;
bool childProp3 = p.prop3;
}
However compiler complains that
"Parent does not contain definition prop1"
The function would take in different subtypes of Class Parent.
All the subclasses have this
public override string prop1 { get; set; }
Is there a way of accomplishing this?
EDIT:
To make the question clearer
I current have a giant if-elseif where i do something like
if(p is Child0){
Child0 ch = p as Child0;
// want to access lots of child properties here
string childProp1 = ch.prop1;
bool childProp2 = ch.prop2;
bool childProp3 = ch.prop3;
}else if(p is Child1){
Child1 ch = p as Child1;
// want to access lots of child properties here
string childProp1 = ch.prop1;
bool childProp2 = ch.prop2;
bool childProp3 = ch.prop3;
}else if(...// and many more
Now I wanted to remove all the redundant code and make one function that can handle all this.

If all child classes need to have the properties (but with different implementations), you should declare them as abstract properties in the base class (Parent), then implement them in the child classes.
If some derived classes won't have those properties, then what would you expect your current GetProps to do?
EDIT: If you're using C# 4 and you definitely can't get a better class design (where the parent class declares the property) you could use dynamic typing:
public void GetProps(Parent p) {
dynamic d = p;
string childProp1 = d.prop1;
bool childProp2 = d.prop2;
bool childProp3 = d.prop3;
// ...
}
I'd treat this as a last resort though...

The solution in case someone need it, it is just to cast the class you receive as a reference as follows:
public void GetProps(Parent p){
..
string childProp1 = ((ChildClass)p).prop1;
...
}

As I understood from your question, you want to access Children Class members from object of Parent Class.
This behavior is not allowed in OOP.
One way can be as suggested by Jon Skeet to create a Abstract base class and implement the required members in Children Classes.
Other way round can be to assign the required values to members of base class in derived class constructor using base construct. I do not know this will solve your problem or not. But Consider the following snippet for example:
public class BaseClass
{
public string FirstName = "Base Class";
public string LastName = "Base Class";
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
base.LastName = "Derived Class";
}
}
internal class Tester
{
private static void Main(string[] args)
{
BaseClass objBaseClass = new BaseClass();
Console.WriteLine("First Name : " + objBaseClass.FirstName);
Console.WriteLine("Last Name : " + objBaseClass.LastName);
DerivedClass objDerivedClass = new DerivedClass();
Console.WriteLine("First Name : " + objDerivedClass.FirstName);
Console.WriteLine("Last Name : " + objDerivedClass.LastName);
BaseClass objBaseDerivedClass = new DerivedClass();
Console.WriteLine("First Name : " + objBaseDerivedClass.FirstName);
Console.WriteLine("Last Name : " + objBaseDerivedClass.LastName);
Console.ReadKey();
}
}
O/P
First Name : Base Class
Last Name : Base Class
First Name : Base Class
Last Name : Derived Class
First Name : Base Class
Last Name : Derived Class
Let me know, if it helps out.

If the property is defined in an intermediate class between parent and child and you don't have a reference to that intermediate class at design time then you could use reflection to get the property. But it sounds like you should be using the most relevant sub parent instead of simply parent.

If I understood you correctly (- I'm assuming Parent is a base class from which Child0 Child1 etc inherit.) – you're just missing a declaration of prop1 in the parent. It won't get in the way, it will simply be overridden.
Check out this example (which returns "child string") and note that child is passed to a method that expects a ParentClass instance.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ChildClass child = new ChildClass();
Text = ParentClass.mymethod(child);
}
}
class ParentClass
{
public virtual string s { get { return "parent string"; } }
public static string mymethod(ParentClass parent)
{
return parent.s;
}
}
class ChildClass : ParentClass
{
public override string s { get { return "child string"; } }
}

Related

Why do we sometimes create an Object of One Class and instantiate it with some other class?

class TestA{
some code.....
}
class TestB{
.....
}
class Program{
void Main(){
TestA obj= new TestB();////When and why do we sometimes do this?
}
}
What are the different scenarios when we would have to refer one object to another class?
We don't. We created a variable called obj, and declared the variable to be of type TestA. That means that that variable can contain a reference to any object this IS-A TestA.
You then create a TestB object. Presumably, TestB derives from TestA, which is not shown in your question. But that means that this new object, is, generally, a TestA, as well as being, specifically, a TestB. We then assign a reference to this object to the obj variable.
Which is fine. It still is a TestB object. It's just that this code, clearly, doesn't intend to use any of it's B-ish nature. Just the core A-ish part that it shares; It's also possible that the TestB class overrides some of TestA's members, in which case it will still demonstrate it's B-ish nature when those members are accessed.
From your code example this approach could be used if TestB inherits from TestA. If you're unsure what inheritance is you should read a bit about Object Oriented programming. Another approach where you would have a class which creates other objects is if you are using a Factory Pattern. There's plenty of information on the web about this pattern too. If you are using a factory pattern you wouldn't use the same constructor approach as in your code though (i.e. you wouldn't expect a new instance of an object to return a different object.)
the answer to this as much as i know, this could be in two cases:
1-Polymorphism.
2-Interfaces.
I'll show u how:
Polymorphism is like :
//an example of Polymorphism.
class FamilyMembers //parent class
{
public virtual void GetData() //it's virtual method cuz it can be overridden later
{
Console.WriteLine("Family");
}
}
class MyBrother : FamilyMembers //child class
{
public override void GetData() //the same method that we wrote before has been overridden
{
Console.WriteLine("Bro");
}
}
class Program
{
static void Main(string[] args)
{
//here's what u asking about
FamilyMembers myBrother = new MyBrother(); //MyBrother is a family member, the system now will choose the GetData() method from the child class MyBrother
myBrother.GetData();
Console.ReadLine();
}
}
Interface is like:
public interface IFamily //the Parent Class
{
//an interface holds the signature of it's child properties and methods but don't set values
//Some properties signatures
int Age { get; set; }
string Name { get; set; }
//some methods
void PrintData();
}
public class MyBrother : IFamily //Child class that inherits from the parent class
{
//some properties, methods, fields
public string Name { get; set; } //public required
public int Age { get; set; } //public required
private string Collage { get; set; } //for my brother only
//constractor that sets the default values when u create the class
public MyBrother()
{
Name = "Cody";
Age = 20;
Collage = "Faculty of engineering";
}
////a method
void IFamily.PrintData()
{
Console.WriteLine("Your name is: " + Name + " and your age is: " + Age + " and you collage is: " + Collage);
}
}
class Program
{
static void Main(string[] args)
{
//now let's try to call the the methods and spawn the child classes :)
//spawn the child class (MyBrother) that inherits from the Family interface
//this is the answer of ur question
IFamily myBrother = new MyBrother(); // the constructor will auto-set the data for me so i don't need to set them
//printing the dude
myBrother.PrintData();
Console.ReadLine();
}
}
I hope this will do :)
We can only do this when class have parent-child relationship,Otherwise it can't be possible to assign one class memory to another class.
Read More...1
Read More...2

Inheritance and access modifier

I have the following simple C# code, but I do not understand the output.
using System;
namespace ConsoleApplication4
{
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
}
class Program
{
static void Main(string[] args)
{
myChild c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}
//Output
//Parent class private string & 3
}
}
When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
I used to believe that inheritance means simply virtually copying and pasting code from a base class to a derived class to reuse code or save key stroke. But after some research, this doesn't seem to be the case. Invoking a inherited method somehow references the base class, which might explains the output in my code.
However, I am still not clear about the inner working of inheritance. For example, I never created an instance of the base class. How should the base class method ( myParent.mymethod() ) exit?
Please help clarity my confusion and point me to some documentations.
Private is the most restrictive access for a field. It means that no other class has access to it, only the current one. Each class has its own set of private fields.
The reason why your application behaves like this is because your mymethod() member is declared public. That means that any class can call it. Since you are inheriting it, you automatically get that method in myParent. It is not copied into myparent, it is inherited. And since it is not overridden by myChild a call to myChild.mymethod() will invoke it on myParent, which accesses the only private name field it can (the one inside myParent).
If you want to inherit the name field, so it will act more like you are expecting, you need to make the field protected instead of private.
class myParent
{
public int id = 3;
protected string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
public myChild()
{
name = "Child class private string";
}
}
Now the variable in myParent is overwritten by myChild when it is instantiated. So, when you make a call to myChild.mymethod() it has access to the new value.
When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
The method c1.mymethod() is defined only in myParent class. Therefore, when you invoke the method, it is going to use the name found in closest proximity to that method. In other words, it will first search the myParent class for that variable and if found it will use it.
If you did this however (make myMethod virtual and override it in the myChild):
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public virtual void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
public override void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
Then it will use the name variable from myChild class since that is the closest one.
You will run into a similar situation if you did this:
public class Person
{
private string name = "John";
public Person(string name)
{
// The parameter is named `name` and the field is named `name`
// so the compiler is going to choose the closest variable.
// In this case, it will assign `name` parameter to itself.
// Visual Studio is nice, in this case, to give you a warning but
// your code will compile and the compiler will just assign `name`
// to `name`
name = name;
// If you did this: this.name = name;
// then the private field will be assigned the value of the parameter
}
}
From C# specification:
Here is how Inhertiance is defined:
Inheritance means that a class implicitly contains all members of its
direct base class type, except for the instance constructors,
destructors and static constructors of the base class.
Now about extending base class.
A derived class extends its direct base class. A derived class can add
new members to those it inherits, but it cannot remove the definition
of an inherited member.
In other word you can extended base class by adding new definitions (or overriding existing ones), but you can't remove any.
And to get it more cleaner:
A derived class can hide (§3.7.1.2) inherited members by declaring new
members with the same name or signature. Note however that hiding an
inherited member does not remove that member—it merely makes that
member inaccessible directly through the derived class.
What you do in your derived class is called hiding and as you can see from quote it doesnt remove that member.
And because in your MyParent class you are using name field defined in same class it will always print what it does. For changing this behaviour you should have look at Virtual properties.
Your new field name in the myChild class does not make the inherited field name from the base class go away! It just hides in. OK, it was hidden already because it was private, but introducing a new field in the derived class still does not make the hidden field go away.
If you want a name that is read-only, you can use a protected virtual property with no set accessor, and override it in the deriving class:
class myParent
{
public int id = 3;
protected virtual string name => "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
protected override string name => "Child class private string";
}
If you want to keep it as a private field, offer a constructor that the deriving class can chain:
class myParent
{
public int id = 3;
private string name;
public myParent() : this("Parent class private string")
{
}
protected myParent(string name)
{
this.name = name;
}
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
public myChild() : base("Child class private string")
{
}
}
This happens because you have used a method inside the parent's context. As you have not overridden myMethod() it will get executed using the private field in that parent's context. if you use method overriding here when you want to get the name of the child's context you can create a child object.
namespace ConsoleApplication2
{
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
public new void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class Program
{
static void Main(string[] args)
{
myChild c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}
//Output
//Parent class private string & 3
}
}
If you want to get the name of the parent's context you can get that using a parent object.
static void Main(string[] args)
{
myParent c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}
If you want to access a field in the derived class, you can define it as protected.
class myParent
{
public int id = 3;
protected string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
and set it in the child constructor
class myChild : myParent
{
public myChild()
{
name = "Child class private string";
}
}
Alternatively you can use the virtual/override keyworkds if you define name as a property { get; set; }
class myParent
{
public int id = 3;
protected virtual string name { get; set; } = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
protected override string name { get; set; } = "Child class private string";
}
I never created an instance of the base class.
It is created internally when you instantiate the derived class.
When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
Basically your original code is equivalent - in terms of its output - to the above case of a virtual name with a new keyword in the derived class
class myChild : myParent
{
new string name { get; set; } = "Child class private string";
}
In that case, the parent's method will display the parent's name, since the child's name is now a different, new variable and it's no longer the one used in the parent's method.

Child Class Properties Not Visible

I am fairly new to c# and very new to abstract classes. Below is an example of the code I am writing. I instantiate my object with Parent obj = new Child2(); or Parent obj = new Child3();
Note that the purpose of this is Child 2 and 3 have different properties but some common, overloaded methods.
My problem is that I can not see any properties in the child class
if I have not described the question in enough detail, please let me know and I will elaborate
namespace ns
{
public class Parent
{
public abstract DataTable ImportToDataTable()
}
public class Child2 : Parent
{
public DelimitedFileDetail InputFile = new DelimitedFileDetail();
public string PropertyforChild1 { get; set; }
public override DataTable ImportToDataTable() { .....code }
}
public class Child3 : Parent
{
public string PropertyforChild2 { get; set; }
public override DataTable ImportToDataTable() { .....code }
}
public class DelimitedFileDetail : Child2
{
public string Name { get; set; }
public ImportTypes FileType { get; set; }
public List<FieldDefinitions> FieldList = new List<FieldDefinitions>();
}
}
You should define your Parent class to be an interface instead of abstract class or base class for that matter
This way your child classes can implement the interface. Then you should use the interface variable to reference child classes/implementations.
Is there a reason you have defined Parent as abstract class? An interface should do since you haven't implemented any abstract members anyway
Well, when you declare the variable in c# with the Parent type, intelisense won't show you the properties of the child.
If you want to use the specific properties of the children you need to declare the variable with the type of the specific children.
So instead of doing:
Parent obj = new Child2();
You should do:
Child2 obj = new Child2();
And so for...
You can't see any properties of the child class because you've told the compiler that obj is of type Parent. If you want to see the properties of the child class you can cast obj to the true type:
Parent obj = new Child2();
string str = ((Child2)obj).PropertyforChild2;
This is, of course, not ideal code. Mostly because then you have to know that obj is of type Child2 and if you know that, why not just give obj the type Child2?

How to Get Base Class Instance from a Derived Class

I don't know if this is possible, but I am trying to get the Base Class instance from a Derived Class. In C#, I can use the base keyword to access properties and methods of the Base Class (of course), but I want to use base itself. Attempting to do so results in a "Use of keyword 'base' is not valid in this context" error.
Example Code
public class SuperParent
{
public int SPID;
public SuperParent()
{
}
}
public class SubChild : SuperParent
{
public SubChild(int pSPID)
{
base.SPID = pSPID;
}
public int BaseSPID
{
get
{
SuperParent sp = base;
return sp.SPID;
}
}
}
If you're working with an instance of the derived class, there is no base instance.
An example:
class A
{
public void Foo() { ... }
}
class B : A
{
public void Bar() { ... }
}
What is not possible within B:
public void Bar()
{
// Use of keyword base not valid in this context
var baseOfThis = base;
}
You can do something like this:
public void Bar()
{
base.Foo();
}
And you can add another method like
public A GetBase()
{
return (A)this;
}
And then you can
public void Bar()
{
var baseOfThis = GetBase();
// equal to:
baseOfThis = (A)this;
}
So this GetBase() method is probably what you want.
The punchline is: If you have an instance of B, it inherits all properties and the non-overriden behaviour of A, but it does not consist of an instance of B which holds an (hidden but automatic) reference to an instance of A. You can cast your B instance to A, but it remains to be an instance of B.
Well you not provide code for your question, but i supsect you want something like
class Base
{
public virtual void Foo()
{
Console.WriteLine("base");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("derived");
}
//// bad
//public Base MyBase
//{
// get
// {
// return base; // Use of keyword 'base' is not valid in this context
// }
//}
// work but...
public Base MyBase
{
get
{
return (Base)this;
}
}
}
But keep in mind that MyBase is really of type Derived
new Derived().MyBase.Foo(); // output "derived"
the problem hasn't been explained as clearly as it could. however, typically, you may be better to use an abstract base class and methods and then override the required methods. you can then use the base.method as required in this case (otherwise you'll have just spun up an instance of the derived class).
public abstract class foo {
public virtual void bar(){..}
}
public class footwo : foo {
public override void bar(){
// do somethng else OR:
return base.bar();
}
}
}
The derived instance IS the base instance. It's just one object instance in memory.
example:
public class A : B
{
}
var thing = new A();
thing is an instance of an A, and is also an instance of a B.
You could for example, write this line:
B thing2 = thing;
Point 1: if you want to create the base class instance within child class than it does not worth. You already have public things accessible in child.
Point 2: If you have initialized child class and now want to get base class "instance" then how can you get that if it's not initialized(Because now the base class instance is not present in the physical memory, and there is just child class instance there)?
I interpreted what they were asking a bit differently than the other answers here so I figured I would offer my $0.02.
// Create a "Parent" class that has some attributes.
public class Parent
{
public string attribute_one { get; set; }
public string attribute_two { get; set; }
public string attribute_three { get; set; }
}
// Define a class called "Child" that inherits the
// attributes of the "Parent" class.
public class Child : Parent
{
public string attribute_four { get; set; }
public string attribute_five { get; set; }
public string attribute_six { get; set; }
}
// Create a new instance of the "Child" class with
// all attributes of the base and derived classes.
Child child = new Child {
attribute_one = "interesting";
attribute_two = "strings";
attribute_three = "to";
attribute_four = "put";
attribute_five = "all";
attribute_six = "together";
};
// Create an instance of the base class that we will
// populate with the derived class attributes.
Parent parent = new Parent();
// Using reflection we are able to get the attributes
// of the base class from the existing derived class.
foreach(PropertyInfo property in child.GetType().BaseType.GetProperties())
{
// Set the values in the base class using the ones
// that were set in the derived class above.
property.SetValue(parent, property.GetValue(child));
}
The result is a new object populated with the base class properties of the child class.
class Parent
{
private Parent _parent;
public Parent()
{
_parent = this;
}
protected Parent GetParent()
{
return _parent;
}
}
class Child : Parent
{
private Parent _parent;
public Child()
{
_parent = base.GetParent();
}
}

C# possible to have a constructor in an abstract class?

I have 1 abstract class that is calling a static method which up until now didn't require any parameters. This has recently changed. In reality the static method exists in another class and sets the value of BaseMessageDirectory, but in this example below I have simplified things...
So now I want to create my derived classes in such a way that they can initialize some required properties in the parent class during the inheritance, is this possible?
For example....
public abstract class ParentClass
{
protected string BaseMessageDirectory;
protected ParentClass(EnumOperationType operationType)
{
if(operationtype == 1)
{
BaseMessageDirectory = "one";
}
else
{
BaseMessageDirectory = "two";
}
}
}
Yes, you can define a constructor, and all child classes will have to call it:
public class Child : ParentClass
{
public Child() : base(EnumOperationType.One) { ... }
}

Categories