in C#, How to access base class variable value from child class - c#

Base Class
class TestBase
{
protected int a;
protected int b;
public TestBase(int i)
{
a = i;
}
protected TestBase()
{
}
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
Child Class
class TestChild:TestBase
{
private string msg;
public void Update (string s)
{
msg = s+ a.ToString();
Console.WriteLine("msg=" + msg);
}
}
Calling
private void btnTest_Click(object sender, EventArgs e)
{
TestBase t = new TestBase(1);
t.Update(100);
}
Result
Hello World 0
Problem
I was hoping to get Hello World 100. Obviously the child class did not access base class variable int a. how can I do that?

First of all, it's not clear what you're trying to accomplish.
There are many problems with this code. First, you should not be creating an instance of TestChild inside a TestBase class method. If you create an instance of TestBase inside btnTest_Click, then there is no way you'll be able to access any of TestChild's methods or data (except that you are creating an instance of TestChild inside TestBase which is bad practice).
The purpose of inheritance is usually to extend the data/methods for a base class, not to use an inherited class inside a base class. Also, with a set of inherited classes, you can achieve polymorphism which is another core principle of Object Oriented Programming. You should get a better understanding of these principles and then the code will start making more sense.

The object you created in TestBtn_Click has nothing to do with the object you created in TestBase.Update. They are two different objects so each have their own a field with different values.
To produce the output you expect, you need to set child.a to this.a in Update:
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.a = this.a;
child.Update("Hello World ");
}
The important thing to understand here is that inheritance does not affect objects. Inheritance only affects classes. The base class members will also be present in the subclass. That's it. Even though objA's type inherits from objB, they are unrelated unless they are the same object.

public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
This is where you are assigning value to variable a, and later you instantiated another instance of TestChild class which is different.
After this instantiation you have to assign the value like
TestChild child = new TestChild();
child.a = i;
child.Update("Hello World ");
Then you shall get your desired result

The child object inside your TestBase doesn't know where is he placed. It doesn't know it is inside of a class.
When you create the child you also create a totally different TestBase object which is not the same as what contains the child. When you create that object a will be initialized to a default value which is 0 in this case.
If you would like to carry the value of a to an other object you should give it to it. For example through the constructor.
Call like this:
TestChild child = new TestChild(a);
Make a constructor like this:
public TestChild(int x) : base(x){}
Unfortunately your concept bleeding from everywhere so it will not work in this form. I recommend to study inheritance more.

This is how to use inheritance:
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Dalmata", "Fuffy", 7);
}
}
class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal(string name, int age)
{
Name = name;
Age = age;
}
}
class Dog : Animal
{
public string Race { get; set; }
public Dog(string race, string name, int age) : base(name, age)
{
Race = race;
}
}
This way, you will acess Name and Age too, even if they are declared in Animal.

you should call your base class this way
class BaseClass
{
int a;
int b;
protected BaseClass()
{ }
protected BaseClass(int i)
{
a = i;
}
protected void Update(int i)
{
a = i;
Console.Write("Hello World ");
}
}
class TestChild : BaseClass
{
public TestChild(int i) : base(i) //send your constuctor to your base class
{ }
public TestChild()
{ }
public void Update(int i)
{
base.Update(i);
Console.Write(i.ToString());
}
}
private void btnTest_Click(object sender, EventArgs e)
{
TestChild t = new TestChild(); // create instance as your child
t.Update(100);
}
create your object as your child class then call your method and let it call your base class
also if wanna access a or b in base class from your child
public int a;
public it so you can access it from instance you created
protected will allow only inside child class to access to it

If you'd like to get the expected result, put a static modifier front of a and/or b variables, like this:
static protected int a;
static protected int b;
After this, if you push that button it will write out:
msg=Hello World 100

Related

How to process data including protected members using extension method in C#

Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:
public class A
{
protected int member1;
public A(int value)
{
member1 = value;
}
}
public class B : A
{
public B (int value) : base(value)
{ }
public void DoSomething()
{
Console.Write(member1 * member1);
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
B obj2 = (B)obj1; // InvalidCastException
obj2.DoSomething();
}
}
And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.
Here's my solution:
Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
Add protected static method which returns the protected member you need.
Create an Extension class for your base class.
In extension class create a private nested class.
Inherit your nested class from your base class.
Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
Create extension method in extension class and call static method of nested class in it.
The sample code is shown below:
public class A
{
protected int member1 = 0;
public A() {}
public A(int value)
{
member1 = value;
}
protected static int GetProtectedMember(A objA)
{
return objA.member1;
}
}
public static class AExtensions
{
public static void DoSomething(this A objA)
{
B.DoSomething(objA);
}
private class B : A
{
public static void DoSomething(A objA)
{
// objA.member1 // it's not allowed
int protectedFromA = A.GetProtectedMember(objA);
int sqr = protectedFromA * protectedFromA;
Console.WriteLine(sqr);
}
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
obj1.DoSomething(); // 25
}
}
This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.

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

Difference between base.i, this.i and object.i in C#

There are two clarifications I need which I am trying to understand.
I see that, I can access the variable "i" using "base" keyword as well as using the object. Is there any difference of it? I think, creation of object is memory consuming and hence we use base keyword itself to call base class members in derived class?
When to use this.i and base .i and object.i?
class Program
{
public Program()
{
i = 20;
}
public readonly int i = 10;
}
class C : Program
{
public C() : base()
{
//base.i = 20;
}
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 20
Console.WriteLine(c.i);//prints 20
Console.WriteLine(this.i); //Also prints 20 :D
}
static void Main()
{
C c = new C();
c.Display();
Console.ReadLine();
}
I tried to accept one answer as that helped me understand few things. But still, my question "the difference ans usage of 3 different styles at my context and in other contexts" is not clear. So please care to share your thoughts on this, I would appreciate it. I am sure there are millions like me who try to understand this :)
As for 1) You can use both to access the property as the sub class has extended it. There will only be a difference if you override that in the sub class or if you decide to create a field with the same name in your sub class.
EDIT:
To override it, you can make it a virtual property in the base class
public class Base
{
public virtual int i {get; set;}
}
public class Sub : Base
{
public override int i { get; set; }
}
Problem 2 : Your StackOverflow
you care creating a new instance of Program every time you create a new instance of Program it seems to be an infinite loop.
class Program
{
Program p = new Program(); // <-- this line here
In your case there is no difference. Difference comes when you have field with same name in base class and derived class(typically we don't have it).
class Program
{
public int i = 10;
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 10
Console.WriteLine(c.i);//prints 20
}
}
base keyword refers to base class, so base.i refers to "member named i" in base class.
Also worth noting that when you access a member with base keyword and it doesn't exist compiler will produce an error.
class Program
{
//public int i = 10; //No field named i
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//Compile time error here
Console.WriteLine(c.i);//this refers to C.i field
}
}
Answer for Question 1
Base you can use when you want to refer you prent class from the child class.
Example :
public class A
{
public int i {get;set;}
}
public class B:A
{
publi void readvalueofi()
{ Console.Writeln(base.i); }
}
This also useful when you override method of parent and want to call parent method from child
Example :
public class Parent
{
public virtual void Print()
{
Console.WriteLine("Print in Parent");
}
}
public class Child : Parent
{
public override void Print()
{
base.Print();
Console.WriteLine("Print in Child");
}
}
Answer for Question 2 :
Reason for StackOverflow Exception
You're creating an private instance of Program when Program is created so this is sort of an endless loop:
your first create Program instance. When this instance is creating it creates a new instance of Program. This instance also creates an instance of Programand again, and again etc.
So basially it creates infinite loop over here.

Cannot access a non-static member of outer type via nested type

I have error
Cannot access a non-static member of outer type 'Project.Neuro' via
nested type 'Project.Neuro.Net'
with code like this (simplified):
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = OtherMethod(); // error is here
}
}
public int OtherMethod() // its outside Neuro.Net class
{
return 123;
}
}
I can move problematic method to Neuro.Net class, but I need this method outside.
Im kind of objective programming newbie.
Thanks in advance.
The problem is that nested classes are not derived classes, so the methods in the outer class are not inherited.
Some options are
Make the method static:
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = Neuro.OtherMethod();
}
}
public static int OtherMethod()
{
return 123;
}
}
Use inheritance instead of nesting classes:
public class Neuro // Neuro has to be public in order to have a public class inherit from it.
{
public static int OtherMethod()
{
return 123;
}
}
public class Net : Neuro
{
public void SomeMethod()
{
int x = OtherMethod();
}
}
Create an instance of Neuro:
class Neuro
{
public class Net
{
public void SomeMethod()
{
Neuro n = new Neuro();
int x = n.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
you need to instantiate an object of type Neuro somewhere in your code and call OtherMethod on it, since OtherMethod is not a static method. Whether you create this object inside of SomeMethod, or pass it as an argument to it is up to you. Something like:
// somewhere in the code
var neuroObject = new Neuro();
// inside SomeMethod()
int x = neuroObject.OtherMethod();
alternatively, you can make OtherMethod static, which will allow you to call it from SomeMethod as you currently are.
Even though class is nested within another class, it is still not obvious which instance of outer class talks to which instance of inner class. I could create an instance of inner class and pass it to the another instance of outer class.
Therefore, you need specific instance to call this OtherMethod().
You can pass the instance on creation:
class Neuro
{
public class Net
{
private Neuro _parent;
public Net(Neuro parent)
{
_parent = parent;
}
public void SomeMethod()
{
_parent.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
I think making an instance of outer class in inner class is not a good option because you may executing business logic on outer class constructor. Making static methods or properties is better option. If you insist making an instance of outer class than you should add another parameter to outer class contructor that not to execute business logic.

Overriding fields or properties in subclasses

I have an abstract base class and I want to declare a field or a property that will have a different value in each class that inherits from this parent class.
I want to define it in the baseclass so I can reference it in a base class method - for example overriding ToString to say "This object is of type property/field".
I have got three ways that I can see of doing this, but I was wondering - what is the best or accepted way of doing this? Newbie question, sorry.
Option 1:
Use an abstract Property and override it on the inherited classes. This benefits from being enforced (you have to override it) and it is clean. But, it feels slightly wrong to return a hard-code value rather than encapsulate a field and it is a few lines of code instead of just. I also have to declare a body for "set" but that is less important (and there is probably a way to avoid that which I am not aware of).
abstract class Father
{
abstract public int MyInt { get; set;}
}
class Son : Father
{
public override int MyInt
{
get { return 1; }
set { }
}
}
Option 2
I can declare a public field (or a protected field) and explicitly override it in the inherited class. The example below will give me a warning to use "new" and I can probably do that, but it feels wrong and it breaks the polymorphism, which was the whole point. Doesn't seem like a good idea...
abstract class Mother
{
public int MyInt = 0;
}
class Daughter : Mother
{
public int MyInt = 1;
}
Option 3
I can use a protected field and set the value in the constructor. This seems pretty tidy but relies on me ensuring the constructor always sets this and with multiple overloaded constructors there is always a chance some code path won't set the value.
abstract class Aunt
{
protected int MyInt;
}
class Niece : Aunt
{
public Niece()
{
MyInt = 1;
}
}
It's a bit of a theoretical question and I guess the answer has to be option 1 as it is the only safe option but I am just getting to grips with C# and wanted to ask this of people with more experience.
Of the three solutions only Option 1 is polymorphic.
Fields by themselves cannot be overridden. Which is exactly why Option 2 returns the new keyword warning.
The solution to the warning is not to append the “new” keyword, but to implement Option 1.
If you need your field to be polymorphic you need to wrap it in a Property.
Option 3 is OK if you don’t need polymorphic behavior. You should remember though, that when at runtime the property MyInt is accessed, the derived class has no control on the value returned. The base class by itself is capable of returning this value.
This is how a truly polymorphic implementation of your property might look, allowing the derived classes to be in control.
abstract class Parent
{
abstract public int MyInt { get; }
}
class Father : Parent
{
public override int MyInt
{
get { /* Apply formula "X" and return a value */ }
}
}
class Mother : Parent
{
public override int MyInt
{
get { /* Apply formula "Y" and return a value */ }
}
}
Option 2 is a non-starter - you can't override fields, you can only hide them.
Personally, I'd go for option 1 every time. I try to keep fields private at all times. That's if you really need to be able to override the property at all, of course. Another option is to have a read-only property in the base class which is set from a constructor parameter:
abstract class Mother
{
private readonly int myInt;
public int MyInt { get { return myInt; } }
protected Mother(int myInt)
{
this.myInt = myInt;
}
}
class Daughter : Mother
{
public Daughter() : base(1)
{
}
}
That's probably the most appropriate approach if the value doesn't change over the lifetime of the instance.
You could do this
class x
{
private int _myInt;
public virtual int myInt { get { return _myInt; } set { _myInt = value; } }
}
class y : x
{
private int _myYInt;
public override int myInt { get { return _myYInt; } set { _myYInt = value; } }
}
virtual lets you get a property a body that does something and still lets sub-classes override it.
option 2 is a bad idea. It will result in something called shadowing; Basically you have two different "MyInt" members, one in the mother, and the other in the daughter. The problem with this, is that methods that are implemented in the mother will reference the mother's "MyInt" while methods implemented in the daughter will reference the daughter's "MyInt". this can cause some serious readability issues, and confusion later down the line.
Personally, I think the best option is 3; because it provides a clear centralized value, and can be referenced internally by children without the hassle of defining their own fields -- which is the problem with option 1.
You could define something like this:
abstract class Father
{
//Do you need it public?
protected readonly int MyInt;
}
class Son : Father
{
public Son()
{
MyInt = 1;
}
}
By setting the value as readonly, it ensures that the value for that class remains unchanged for the lifetime of the object.
I suppose the next question is: why do you need it?
If you are building a class and you want there to be a base value for the property, then use the virtual keyword in the base class. This allows you to optionally override the property.
Using your example above:
//you may want to also use interfaces.
interface IFather
{
int MyInt { get; set; }
}
public class Father : IFather
{
//defaulting the value of this property to 1
private int myInt = 1;
public virtual int MyInt
{
get { return myInt; }
set { myInt = value; }
}
}
public class Son : Father
{
public override int MyInt
{
get {
//demonstrating that you can access base.properties
//this will return 1 from the base class
int baseInt = base.MyInt;
//add 1 and return new value
return baseInt + 1;
}
set
{
//sets the value of the property
base.MyInt = value;
}
}
}
In a program:
Son son = new Son();
//son.MyInt will equal 2
You can go with option 3 if you modify your abstract base class to require the property value in the constructor, you won't miss any paths. I'd really consider this option.
abstract class Aunt
{
protected int MyInt;
protected Aunt(int myInt)
{
MyInt = myInt;
}
}
Of course, you then still have the option of making the field private and then, depending on the need, exposing a protected or public property getter.
I'd go with option 3, but have an abstract setMyInt method that subclasses are forced to implement. This way you won't have the problem of a derived class forgetting to set it in the constructor.
abstract class Base
{
protected int myInt;
protected abstract void setMyInt();
}
class Derived : Base
{
override protected void setMyInt()
{
myInt = 3;
}
}
By the way, with option one, if you don't specify set; in your abstract base class property, the derived class won't have to implement it.
abstract class Father
{
abstract public int MyInt { get; }
}
class Son : Father
{
public override int MyInt
{
get { return 1; }
}
}
I did this...
namespace Core.Text.Menus
{
public abstract class AbstractBaseClass
{
public string SELECT_MODEL;
public string BROWSE_RECORDS;
public string SETUP;
}
}
namespace Core.Text.Menus
{
public class English : AbstractBaseClass
{
public English()
{
base.SELECT_MODEL = "Select Model";
base.BROWSE_RECORDS = "Browse Measurements";
base.SETUP = "Setup Instrument";
}
}
}
This way you can still use fields.
The example implementation when you want to have an abstract class with implementation. Subclasses must:
Parameterize the implementation of an abstract class.
Fully inherit the implementation of the abstract class;
Have your own implementation.
In this case, the properties that are necessary for the implementation should not be available for use except for the abstract class and its own subclass.
internal abstract class AbstractClass
{
//Properties for parameterization from concrete class
protected abstract string Param1 { get; }
protected abstract string Param2 { get; }
//Internal fields need for manage state of object
private string var1;
private string var2;
internal AbstractClass(string _var1, string _var2)
{
this.var1 = _var1;
this.var2 = _var2;
}
internal void CalcResult()
{
//The result calculation uses Param1, Param2, var1, var2;
}
}
internal class ConcreteClassFirst : AbstractClass
{
private string param1;
private string param2;
protected override string Param1 { get { return param1; } }
protected override string Param2 { get { return param2; } }
public ConcreteClassFirst(string _var1, string _var2) : base(_var1, _var2) { }
internal void CalcParams()
{
//The calculation param1 and param2
}
}
internal class ConcreteClassSecond : AbstractClass
{
private string param1;
private string param2;
protected override string Param1 { get { return param1; } }
protected override string Param2 { get { return param2; } }
public ConcreteClassSecond(string _var1, string _var2) : base(_var1, _var2) { }
internal void CalcParams()
{
//The calculation param1 and param2
}
}
static void Main(string[] args)
{
string var1_1 = "val1_1";
string var1_2 = "val1_2";
ConcreteClassFirst concreteClassFirst = new ConcreteClassFirst(var1_1, var1_2);
concreteClassFirst.CalcParams();
concreteClassFirst.CalcResult();
string var2_1 = "val2_1";
string var2_2 = "val2_2";
ConcreteClassSecond concreteClassSecond = new ConcreteClassSecond(var2_1, var2_2);
concreteClassSecond.CalcParams();
concreteClassSecond.CalcResult();
//Param1 and Param2 are not visible in main method
}

Categories