Given 2 Types
class A { public virtual void Hello() { Console.WriteLine("A"); } }
class B : A { public override void Hello() { Console.WriteLine("B"); } }
and an instance of 'B'
B b = new B();
Can I access the Hello() method of A thru b ? (I can think of exposing A as property in B but not sure if there is another way)
I knew this is possible in c++ but was scratching my head in c#.
PS:Please no conversations around 'why do you want this?' or 'this is a bad design' etc.
Not from the outside.
From the inside, the instance can call that, via base.Hello(), so you could add a:
public void Foo() { base.Hello(); }
It is not possible in c#. Sorry.
You can try shadowing:
class A { public virtual void Hello() { Console.WriteLine("A"); } }
class B : A { public new void Hello() { Console.WriteLine("B"); } }
Then you can do:
A b = new B();
b.Hello(); //prints A
(B)b).Hello(); //prints B
B b1 = new B();
b1.Hello(); //prints B
Related
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)
{
}
}
It's a question of overriding in C#.
When I use following code:
class Program
{
class A
{
public virtual void callme()
{
Console.WriteLine("this is A");
}
}
class B : A
{
public new virtual void callme()
{
Console.WriteLine("this is B");
}
}
class C : B
{
public override void callme()
{
Console.WriteLine("this is C");
}
}
static void Main(string[] args)
{
A obj = new C();
obj.callme();
Console.ReadKey();
}
}
OUTPUT: This is A
And when I use:
class Program
{
class A
{
public virtual void callme()
{
Console.WriteLine("This is A.");
}
}
class B : A
{
public override void callme()
{
Console.WriteLine("This is B.");
}
}
class C : B
{
public override void callme()
{
Console.WriteLine("This is C.");
}
}
static void Main(string[] args)
{
A obj = new C();
obj.callme();
Console.ReadKey();
}
}
OUTPUT: This is C.
So if I make a method virtual in the subsequent classes (A as well as B), why it calls the last method, and if the B class is overriding A and C is overriding B then it's calling C's method.
Please explain.
In the 1st case, B is shadowing A and C is overriding the shadow in B. So as long as the reference type is A, it will call the A method.
In the 2nd case B is overriding A and C is overriding B (so it's overriding A).
See: Differences Between Shadowing and Overriding
Check the compiler warning:
Warning 1 '..Program.B.callme()' hides inherited member
'..Program.A.callme()'. To make the current member override that
implementation, add the override keyword. Otherwise add the new
keyword. ..\Program.cs 44 33 Test
It states that method in B hides the method in A. When you override the method in C; it simply overrides the method in B not in A (compiler assumes that you callme in class B is a new method). So when you call A.callme, since the method in A is not overriden, it returns "this is A".
Is it possible for the a.doStuff() method to print "B did stuff" without editing the A class? If so, how would I do that?
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
a.doStuff();
b.doStuff();
Console.ReadLine();
}
}
class A
{
public void doStuff()
{
Console.WriteLine("A did stuff");
}
}
class B : A
{
public void doStuff()
{
Console.WriteLine("B did stuff");
}
}
I'm modding a steam game, Terraria. And I don't want to decompile and recompile it all because that will screw with steam. My program 'injects' into Terraria via XNA. I can use the update() and draw() methods from XNA to mod some things. But it's pretty limited. I wan't to override base methods to mod more things (worldgen for example).
Yes, if you declare doStuff as virtual in A and then override in B.
class A
{
public virtual void doStuff()
{
Console.WriteLine("A did stuff");
}
}
class B : A
{
public override void doStuff()
{
Console.WriteLine("B did stuff");
}
}
Since B is effectively A through inheritance and the method is overloaded.
A a = new B();
a.doStuff();
The code for class A & B you have posted will anyways generate below compiler warning and will ask to use the new keyword on class B, although it will compile:
The keyword new is required on 'B.doStuff()' because it hides inherited member 'A.doStuff()'
Use method hiding along with new and virtual keyword in class Mapper and class B as follows:
class Program
{
static void Main(string[] args)
{
Mapper a = new B(); //notice this line
B b = new B();
a.doStuff();
b.doStuff();
Console.ReadLine();
}
}
class A
{
public void doStuff()
{
Console.WriteLine("A did stuff");
}
}
class Mapper : A
{
new public virtual void doStuff() //notice the new and virtual keywords here which will all to hide or override the base class implementation
{
Console.WriteLine("Mapper did stuff");
}
}
class B : Mapper
{
public override void doStuff()
{
Console.WriteLine("B did stuff");
}
}
Fist of all, I will use virtual and override
for example, base class A has method A.do(), inherited class B has B.do() which overrides A's.
if I call (B as A).do(), which do() would it execute?
or, if there is a method void mymethod(A a) {a.do()}, now I call it by B b; mymethod(b), would it execute b.do()?
The most top override method always will be called, i.e. b.Do() or (b as A).Do() or ((A)b).Do() will call B.Do().
I don't know a way how to call a base method from child class if child class overrides it.
public class A
{
public virtual void Do() { Console.Write("a"); }
public void Do2() { Console.Write("a2"); }
}
public class B : A
{
public override void Do() { Console.Write("b"); }
public new void Do2() { Console.Write("b2"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = b;
b.Do(); //b
( b as A ).Do(); //b
a.Do(); //b
( (A)b ).Do(); //b
( b as A ).Do2(); //a2
( (A)b ).Do2(); //a2
( b ).Do2(); //b2
}
}
Output:
b b b b
a2 a2 b2
It entirely depends on whether the do() method was declared virtual or not. If it is not virtual then A.do() is called. If it is virtual then B.do() is called. It is the virtual keyword that enables polymorphism and allows calling a method independent of the type of the reference.
There is no mechanism in C# that allows directly calling a virtual A.do() method from a B object reference. The only exception is using base.do() inside an instance method of class B.
public class A
{
public A() { }
public void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public void Do() { Console.Write("B"); }
}
class Program
{
static void Main(string[] args)
{
B b = new B();
b.Do(); //<-- outputs B
(b as A).Do(); //<-- outputs A
}
}
compiler warns for hiding not overriding:
Warning 1 'ConsoleApplication5.B.Do()' hides inherited member
'ConsoleApplication5.A.Do()'. Use the new keyword if hiding was
intended. c:\Program.cs 18 21 ConsoleApplication5
that is since you are not overriding anything, but simply hiding the method from A.
however
public class A
{
public A() { }
public virtual void Do() { Console.Write("A"); }
}
public class B : A
{
public B() { }
public override void Do() { Console.Write("B"); }
}
calls B twice, when method is overridden.
here's what I am trying to do
class A
{
virtual void foo();
}
class B : A
{
virtual override void foo();
}
class C : B
{
override void foo();
}
so what I want to see when calling C.foo() is
A.foo(), B.foo(), C.foo()
but I dont think virtual override can be used in the same function definition. How would I go around this?
Thanks
-Mike
Overridden functions are automatically virtual, unless explicitly declared sealed.
Note that calling C.Foo() will not call B.Foo() or A.Foo() unless C.Foo manually calls base.Foo().
code should work like this:
public class A
{
public virtual void foo() {}
}
public class B : A
{
public override void foo() {}
}
class C : B
{
public override void foo() {}
}
so long as foo is accessible. no need for 'virtual' in B
Is this what you're looking for?
class A
{
public virtual void foo()
{
MessageBox.Show("A");
}
}
class B : A
{
public override void foo()
{
MessageBox.Show("B");
base.foo();
}
}
class C : B
{
public override void foo()
{
MessageBox.Show("C");
base.foo();
}
}
C c = new C();
c.foo();