I'm using IoC to define some behavior in my inherited class. I have a property
protected virtual bool UsesThing { get { return true; } }
in my top-level class.
In my inherited class I have
protected override bool UsesThing { get { return false; } }
I'm using the property in my top level class, and it's using the top-level value. Is there a way to make it use the inherited value? I thought that's what virtual was supposed to do.
Code Example:
using System;
public class Program
{
public static void Main()
{
B b = new B();
b.PrintThing();
//I want this to print the value for B
}
public class A
{
protected virtual bool Enabled
{
get
{
return true;
}
}
public void PrintThing()
{
Console.WriteLine(this.Enabled.ToString());
}
}
public class B : A
{
protected override bool Enabled
{
get
{
return false;
}
}
}
}
Here's a Dot Net Fiddle demonstrating my problem
You could do something like this:
https://dotnetfiddle.net/SOiLni
A in of itself knows nothing of B's implementation, so you have to instantiate an object of B in order to access its overriden property.
Slightly modified version of your fiddle:
public class Program
{
public static void Main()
{
A a = new A();
a.PrintThing();
A newA = new B();
newA.PrintThing();
}
public class A
{
protected virtual bool Enabled
{
get
{
return true;
}
}
public void PrintThing()
{
Console.WriteLine(this.Enabled.ToString());
}
}
public class B : A
{
protected override bool Enabled
{
get
{
return false;
}
}
}
}
Given your code example, A's Enabled will be printed, as it should.
When you create an A it knows nothing about B, so polymorphically, you can't expect it to use its value. This makes since, because if you had a class C that also derived from A, it wouldn't know what to use!
On the other hand, if you had written:
public static void Main()
{
A a = new B();
a.PrintThing();
}
You would expect (correctly) that it would use B's override, as you created an instance of that type.
You must have some other issue with your code. This code will print 'true' and 'false' respectively:
public class BaseClass {
public virtual bool DoesSomething {
get {
return true;
}
}
public void Print() {
Console.WriteLine(DoesSomething);
}
}
public class ChildClass : BaseClass {
public override bool DoesSomething {
get {
return false;
}
}
}
Then using these classes:
BaseClass bc = new BaseClass();
bc.Print();
ChildClass sc = new ChildClass();
sc.Print();
If I was to guess you are probably creating instances of the parent class even though your intention is to create instances of the child class.
Related
Okay so I am working on a project that haves a abstract public abstract bool IsFull { get; } this is how the school wants me to set it up. I was trying to figure out a work around that but I can't. I have a few files not sure if I want them all to post. so in my class it is inherited from a different class. so when I initiate it from the program cs class I can't get the boolean to change with a simple IsFull = true. I tried IsFull.Equal(true); but read that just a comparison attribute. I will show my code. Remember this is 100% new to me so if you asked questions why don't i do it this way the answer is I never was taught that lol.
So is there a way I can override it within the sweettooth class?
My Ninja class
using System.Collections.Generic;
using IronNinja.Interfaces;
namespace IronNinja.Models
{
abstract class Ninja
{
protected int calorieIntake;
public List<IConsumable> ConsumptionHistory;
public Ninja()
{
calorieIntake = 0;
ConsumptionHistory = new List<IConsumable>();
}
public abstract bool IsFull { get; }
public abstract void Consume(IConsumable item);
}
}
my inherited class sweettooth
using IronNinja.Interfaces;
namespace IronNinja.Models
{
class SweetTooth : Ninja
{
public string Name;
public SweetTooth(string name)
{
Name = name;
}
public override bool IsFull { get; }
public override void Consume(IConsumable item)
{
// provide override for Consume
int sweet = 0;
if (calorieIntake >= 1500)
{
}
else
{
if (item.IsSweet)
{
sweet = 10;
}
ConsumptionHistory.Add(item);
calorieIntake += item.Calories + sweet;
}
item.GetInfo();
}
}
}
Lastly my Programs .cs file
using System;
using IronNinja.Models;
namespace IronNinja
{
class Program
{
static void Main(string[] args)
{
Buffet hungryJack = new Buffet();
SweetTooth Albert = new SweetTooth("Alby");
while (!Albert.IsFull)
{
Albert.Consume(hungryJack.Serve());
}
foreach (Food item in Albert.ConsumptionHistory)
{
Console.WriteLine(item.Name);
System.Console.WriteLine(item.GetInfo());
}
}
}
}
From my understanding, the IsFull property can simply provide the logic to return whether or not the SweetTooth is full:
public override bool IsFull => calorieIntake >= 1500;
And then in SweetTooth.Consume you would check if they are full before consuming more consumables:
public override void Consume(IConsumable item)
{
// provide override for Consume
int sweet = 0;
if (IsFull)
{
return;
}
else
{
if (item.IsSweet)
{
sweet = 10;
}
ConsumptionHistory.Add(item);
calorieIntake += item.Calories + sweet;
}
item.GetInfo();
}
You simply can't, by language design. You can't make your subclass "more permissive" than the parent class.
If you want to assign IsFull property, you have to do it into the SweetTooth class through the constructor. Generally if you set a property with private setter is because you want to manage its state internally and do not let the client code to handle it.
Then, change the SweetTooth constructor as per below:
public SweetTooth(string name, bool isFull)
{
Name = name;
IsFull = isFull;
}
The alternative is to add a private backing field, but again you can edit this only internally:
private bool _isFull;
public override bool IsFull => _isFull;
The Equal method compares two values. In your specific case you called bool.Equals(bool) overload which worked as Albert.IsFull == true
So lets say I have two classes. Class A and Class B like this:
Class A
{
B classB;
public A
{
classB = new B();
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B
{
classA = new A();
}
public void funcIHaveToUseInClassA()
{
}
}
As you can see both classes contain functions that need to be used in the other class. Class A has a function that class B has to use and the other way around. No I can't just put the functions in the other class because they heavily rely on the class they are currently in. So how would I go about doing this? With my method I create an infinite loop and get a stack overflow exception. I hope someone can help me out, thanks in advance.
EDIT:
People are asking me why I need these 2 classes to rely on each other so here it is: Class A manages everything that has to do with a WebBrowser control and class B Manages everything that has to do with a certain page in my program. Class A is being used by multiple pages, which is the reason it needs to be a seperate class. Class A sometimes needs to push info to class B. Class B sometimes needs info from the WebBrowser control class A is managing and that is why it calls a function.
Make classB and classA into public properties and initialize them from another class instead of constructor.
class A
{
public B classB { get; set; }
public void funcIHaveToUseInClassB()
{
}
public void anotherF()
{
classB.funcIHaveToUseInClassA();
}
}
class B
{
public A classA { get; set; }
public void funcIHaveToUseInClassA()
{
}
public void anotherF()
{
classA.funcIHaveToUseInClassB();
}
}
static void main()
{
// entry point
var a = new A();
var b = new B();
a.classB = b;
b.classA = a;
// do what ever you want with a and b
}
You need to pass an instance of one of your classes to the constructor of the other class.
Try this:
Class A
{
B classB;
public A()
{
classB = new B(this);
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B(A arg)
{
classA = arg;
}
public void funcIHaveToUseInClassA()
{
}
}
Update
Or just pass in the instance as a parameter to the methods like in Matt Jacobsen's answer.
Create a private and public accessor, and instantiate the property only when the private object is null, like so:
class A
{
private B _b;
public B b {
get {
if (_b == null) _b = new B();
return _b;
}
}
// Constructor can now be empty
public A()
{
}
}
Pass your reference from B/A in to A/B each time you need to use it. You don't need the constructors.
Class A
{
public void funcIHaveToUseFromClassB(B classB)
{
}
}
Class B
{
public void funcIHaveToUseFromClassA(A classA)
{
}
}
I have to override a function in a base class in such a way that calls to inherited functions also lead to calls to this overridden function instead of the base implementation.
class base_class
{
string abc;
public int get_1()
{
return 1;
}
public int get_number()
{
return get_1()+1;
}
}
class der_class : base_class
{
public int get_1()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
der_class abc = new der_class();
Console.WriteLine(abc.get_number());
Console.ReadKey();
}
}
This prints 2. How can I get the output to be 3 by making the get_number to call overridden get_1?
You need the override keyword to actually override a method, otherwise you are hiding it.
class der_class : base_class
{
// note the word override here!
public override int get_1()
{
return 2;
}
}
Also, you need to make the method virtual in the base class:
class base_class
{
string abc;
// note the word virtual here!
public virtual int get_1()
{
return 1;
}
public int get_number()
{
return get_1()+1;
}
}
I'm wondering why in the following example does the base method always get called even though I'm overriding it when the Factory Pattern "Builder" returns a new instance of the object?
interface FactoryInter
{
void MakeDetails();
}
class Builder {
public static Builder getObject(string obj)
{
if(obj == "Cont")
{
return new Cont();
}else{
return new Builder();
}
}
public void MakeDetails()
{
Console.WriteLine("I will always get called..");
}
}
class Cont : Builder, FactoryInter {
public void MakeDetails()
{
Console.WriteLine("Hello..");
}
}
public class Test
{
public static void Main()
{
Builder b = new Builder();
b = Builder.getObject("Cont");
b.MakeDetails();
// your code goes here
}
}
Any help would be greatly appreciated
You do not override it. You are hiding it. Method Cont.MakeDetails() is hiding the base class's MakeDetails method. For more details please see the below example:
class Base
{
public void Hidden()
{
Console.WriteLine("Base!");
}
public virtual void Overrideable()
{
Console.WriteLine("Overridable BASE.");
}
}
class Derived : Base
{
public void Hidden()
{
Console.WriteLine("Derived");
}
public override void Overrideable()
{
Console.WriteLine("Overrideable DERIVED");
}
}
Now testing them yields these results:
var bas = new Base();
var der = new Derived();
bas.Hidden(); //This outputs Base!
der.Hidden(); //This outputs Derived
((Base)der).Hidden();
//The above outputs Base! because you are essentially referencing the hidden method!
//Both the below output Overrideable DERIVED
der.Overrideable();
((Base)der).Overrideable();
To override it, mark the base method as virtual and the derived one as override.
I have a set of objects inherited from ObjBase class. Processing logic is pretty same for all of these objects with a little differences. How do I keep all logic in public virtual void Work(ObjBase o) and process specific logic in overridden methods.
Example below is something I want to achieve, but it can't compile because of overriding parameters.
What be the better way to implement that ?
class Foo
{
public void Do(ObjBase o)
{
switch (o.RequestType)
{
case "A":
new ProcA<ObjA>().Work(o);
break;
case "B":
new ProcB<ObjB>().Work(o);
break;
}
}
}
class ObjBase { }
class ObjA : ObjBase { }
class ObjB : ObjBase { }
class ProcBase
{
public virtual void Work(ObjBase o)
{
//Common things to do...
}
}
class ProcA<T> : ProcBase where T : ObjBase
{
public override void Work(ObjA o)
{
base.Work(o);
//DoSpecificWork
}
}
class ProcB<T> : ProcBase where T : ObjBase
{
public override void Work(ObjB o)
{
base.Work(o);
//DoSpecificWork
}
}
Thank you
Basically, you can't. I would advise that you put the custom code in the virtual method (i.e. also add an override), and cast - for example:
public override void Work(ObjBase o)
{
base.Work(o);
var a = o as ObjA;
if (a != null)
{
// do a-specific things
}
}
This ensures that your logic happens even if they call the base-type's method.
You could also provide a new overload, for example:
public void Work(ObjA o)
{
Work((ObjBase)o);
}
But it is unclear that this adds much value.