I'm relatively new to programming so excuse me if I get some terms wrong (I've learned the concepts, I just haven't actually used most of them).
Trouble: I currently have a class I'll call Bob its parent class is Cody, Cody has method call Foo(). I want Bob to have the Foo() method as well, except with a few extra lines of code. I've attempted to do Foo() : base(), however that doesn't seem to work like. Is there some simple solution to this?
You can override Foo in the derived class and call the overridden base class implementation using base.Foo():
class Cody
{
public virtual void Foo()
{
Console.WriteLine("Cody says: Hello World!");
}
}
class Bob : Cody
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Bob says: Hello World!");
base.Foo();
}
}
Output of new Bob().Foo():
Cody says: Hello World!
Bob says: Hello World!
Cody says: Hello World!
Constructors use a slightly different syntax to call the constructor in a base class, because they have the requirement that the base class constructor must be called before the constructor in the derived class:
class Cody
{
public Cody()
{
}
}
class Bob : Cody
{
public Bob() : base()
{
}
}
The standard form (without polymorphism) is:
class Cody
{
public void Foo ()
{
}
}
class Bob : Cody
{
public new void Foo()
{
base.Foo(); // Cody.Foo()
// extra stuff
}
}
If you want polymorphism, the following 2 lines change:
// Cody
public virtual void Foo ()
// Bob
public override void Foo()
The difference shows when calling on a Bob instance through a Cody reference:
Bob b = new Bob();
Cody c = b;
b.Foo(); // always Bob.Foo()
c.Foo(); // when virtual, Bob.Foo(), else Cody.Foo()
You need to mark the base method as virtual, override it in the inherited class, and then call the base that way. You can either call the base before or after your code in the "Cody" class it is up to you on calling order.
class Bob
{
public virtual void Foo()
{
}
}
class Cody
{
public override void Foo()
{
base.Foo()
// your code
}
}
Related
If I had this code:
public virtual void Foo()
{
void Bar()
{
// do important stuff for Foo
}
}
// In a child class:
public override void Foo()
{
Bar(); // Doesn't work
base.Bar(); // Also doesn't work
}
Is there anyway to call the local function defined in Bar inside of Foo without making Bar a normal method?
Is there anyway to call the local function defined in Bar inside of Foo without making Bar a normal method?
There is no by-design way. That's what "local" means. A local is accessible by name only by code in the location of the declaration; that's why they're called "locals".
Is there "any" way? Sure, you could do all kinds of shenanigans with reflection and decompilation and unsafe code and so on. Please don't. Those are implementation details of the compiler; don't try to reverse-engineer them and certainly do not rely on any implementation choice the compiler team has made being permanent!
Yes, you can pass around a delegate to it just as you do with any lambda expression. And no, this doesn't break any "rules," and we do it in Javascript all the time, under the module pattern, or whatever it's called.
public class MyBase
{
protected Action Foo()
{
return Local;
void Local()
{
Console.WriteLine("Hello world");
}
}
}
public class MyDerived : MyBase
{
public void HelloWorld()
{
var f = Foo();
f();
}
}
public class Program
{
public static void Main()
{
var o = new MyDerived();
o.HelloWorld();
}
}
Output:
Hello world
Link to DotNetFiddle
I have a class A with a static method, and a derived class B. You can call Foo(), declared in A, on both A and B:
public class A
{
public static void Foo()
{
// How to get typeof(B) here if Foo called by using class B?
}
}
public class B : A
{
}
...
static class Program
{
static void Main()
{
B.Foo();
}
}
Now inside Foo(), how can I find out on which type Foo() was called?
I can't use keyword this, because I do not create any objects here. I have tried already:
MethodBase.GetCurrentMethod().DeclaringType
and
MethodBase.GetCurrentMethod().ReflectedType
but they both return me the typeof(A), while I need to get the typeof(B).
I'm not sure exactly what you want to achieve, and agree with the comments that perhaps you can approach this a different way. Saying this, could you do what you need with a generic base class?
public class AB<T>
{
public static void Foo()
{
Console.WriteLine(typeof(T));
}
}
public class A : AB<A> { }
public class B : AB<B> { }
A.Foo(); // A
B.Foo(); // B
There are no way to obtain typeof(B) inside of static method Foo() in this case. The possible solution is to use parameters in Foo method.
Thanks to #Jon Skeet and #CodeCaster.
Here is the code i got confused with.
class foo
{
public string fname;
public virtual void print()
{
Console.WriteLine("I am the boss i am the virtual");
}
};
class bar : foo
{
public override void print()
{
Console.WriteLine("I am the first derivative");
}
};
class tar : bar
{
public new virtual void print()
{
Console.WriteLine("I am the newly born baby with a new keyword!!!!");
}
};
class jar : tar
{
public override void print()
{
Console.WriteLine("i am created in derivative of tar i.e, jar");
}
};
class Program
{
static void Main(string[] args)
{
foo obj1 = new foo();
obj1.fname = "neha";
foo objtar = new jar(); //here lies the confusion why bar print() is called
objtar.print();
}
}
In this code i am calling print method using 3rd level derived class(jar) object and base(foo). I am confused by looking at the output it is
I am the first derivative
Can someone explain the reason behind it. I am a newb to c# need help....
That is because you call print on an instance of foo. The new keyword will only be applied on typed instances of that type.
The rules of inheritance don't apply any more since tar.print is new.
This is all documented behavior which you can find on MSDN.
So this will work as you expected:
jar objtar = new jar();
objtar.print();
Expecting "Hello from the derived." but getting "Hello from the base.".
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public virtual new void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
So why isn't the derived class's method called. And more importantly, how can I get the derived classes method to get called without casting x to the Derived type?
In my actual application, IBase has several other related methods and Derived only replaces two of the methods in IBase.
When you use the new modifier you are specifically saying that the method is not part of the virtual dispatch chain for that hierarchy, so calling the method by the same name in the base class will not result in redirection to the child class. If you mark the method with override instead of new then you will see the virtual dispatch that you are expecting to see.
You will also need to remove virtual from the derived class's method as you cannot mark an override method as virtual (it already is).
If you really don't want to override the method then it may be more appropriate, in your situation, to not use inheritance at all. You may simply want to use interfaces exclusively:
public interface IFoo
{
void Foo();
}
public class A : IFoo
{
public void Foo()
{
Console.WriteLine("I am A, hear me roar!");
}
}
public class B : IFoo
{
public void Foo()
{
Console.WriteLine("I am B, hear me roar!");
}
}
private static void Main(string[] args)
{
IFoo foo = new A();
foo.Foo();
foo = new B();
foo.Foo();
Console.WriteLine();
Console.WriteLine("Press any key to exit . . .");
Console.ReadKey(true);
}
This is basic polymorphism at work.
For the behavior you're looking for, you would need to set your derived method to override the inherited method:
public class Derived : Base
{
public override void Method()
{
Console.WriteLine("Hello from the derived.");
}
}
Use the override keyword instead of virtual new in your child class.
Therefore, your code should look like:
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
public override void Method() // The magic happens here!
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
As described here, the new keyword is used to hide the parent method, which is not what you're looking for.
new keyword creates a new method and says that the base method is hidden. But it is only for consumers of your derived class, since the base class code does not know anything about it.
override keyword overrides the base class implementation with a new one.
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
// the next line was changed.
public override void Method()
{
Console.WriteLine("Hello from the derived.");
// note that if you want to call the original implementation, you do it like this:
base.Method();
}
}
static void Main(string[] args)
{
Base x = new Derived();
x.Method();
}
}
The new'd Method in Derived only exists in a Derived instance, where it effectively hides the base implementation.
But IBase type only knows the Base's implementation, so it calls that.
To answer your question, to call the derived's implementation you'd do:
Derived d = new Derived();
d.Method();
((IBase)d).Method();
//Prints:
//Hello from the derived.
//Hello from the base.
1) Why does the following codes differ.
C#:
class Base
{
public void foo()
{
System.Console.WriteLine("base");
}
}
class Derived : Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public new void foo()
{
System.Console.WriteLine("derived");
}
}
Java:
class Base {
public void foo() {
System.out.println("Base");
}
}
class Derived extends Base {
public void foo() {
System.out.println("Derived");
}
public static void main(String []s) {
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
}
2) When migrating from one language to another what are the things we need to ensure for smooth transition.
The reason is that in Java, methods are virtual by default. In C#, virtual methods must explicitly be marked as such.
The following C# code is equivalent to the Java code - note the use of virtual in the base class and override in the derived class:
class Base
{
public virtual void foo()
{
System.Console.WriteLine("base");
}
}
class Derived
: Base
{
static void Main(string[] args)
{
Base b = new Base();
b.foo();
b = new Derived();
b.foo();
}
public override void foo()
{
System.Console.WriteLine("derived");
}
}
The C# code you posted hides the method foo in the class Derived. This is something you normally don't want to do, because it will cause problems with inheritance.
Using the classes you posted, the following code will output different things, although it's always the same instance:
Base b = new Derived();
b.foo(); // writes "base"
((Derived)b).foo(); // writes "derived"
The fixed code I provided above will output "derived" in both cases.
The C# code will compile with warnings, since you are hiding methods there.
In Java, class-methods are always virtual, whereas in C# they're not, and you have to mark them explicitly as 'virtual'.
In C#, you'll have to do this:
public class Base
{
public virtual void Foo()
{
Console.WriteLine ("Base");
}
}
public class Derived : Base
{
public override void Foo()
{
Console.WriteLine ("Derived.");
}
}