According to this similar StackOverflow question and other articles, C# methods are "not virtual" by default, which I take it to mean that you cannot override them in a derived class.
If that is true, could you please explain to me how, in the example below, how I am able to implement the property LastName in the Child class which inherits from Base class without the property being marked as "virtual" inh the base class? Does the Child.LastName property "hide" (VB "Shadows") the same property in the base class? if so, why is the "new" key word not used in the Child.LastName pproperty to indicate this?
This test example seems to suggest to me that methods and virtual by default and, in the case of the LastName property, "overrrides" is implied, but I'm pretty sure that this is not the case.
What am I missing?
public class BaseClass
{
private string _FirstName;
public virtual string FirstName {
get { return _FirstName; }
set { _FirstName = value; }
}
private string _LastName;
public string LastName {
get { return _LastName; }
set { _LastName = value; }
}
public void Go()
{
MessageBox.Show("Going at default speed in Base Class");
}
public void Go(int speed)
{
MessageBox.Show("Going at " + speed.ToString() + " in Base Class");
}
}
public class Child : BaseClass
{
public override string FirstName {
get { return "Childs First Name"; }
set { base.FirstName = value; }
}
public string LastName {
get { return "Child's Last Name"; }
set { base.LastName = value; }
}
public void Go()
{
MessageBox.Show("Going in Child Class");
}
public void Go(int speed)
{
MessageBox.Show("Going at " + speed.ToString() + " in Child Class");
}
}
Methods are not virtual in C# by default. LastName in Child class hides the LastName from the BaseClass. As far as i can remember, this code can even compile, but warning will be provided by compiler, telling that new keyword should be used.
They're non-virtual by default.
The subclass hides the base's LastName property.
If you write:
BaseClass b = new Child(...);
Console.WriteLine(b.LastName);
You will see the base implementation is called.
The compiler will warn you about this when you compile the above code. It's standard practice to mark a member which hides a base's member as new.
public new string LastName {
get { return "Child's Last Name"; }
set { base.LastName = value; }
}
This is a very common C# programming interview question :)
A good understanding of Polymorphism will clear this up:
Polymorphism (C# Programming Guide)
Hiding Base Class Members with New Members
If you want your derived member to have the same name as a member in a base class, but you do not want it to participate in virtual invocation, you can use the new keyword. The new keyword is put before the return type of a class member that is being replaced. The following code provides an example:
public class BaseClass
{
public void DoWork() { WorkField++; }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { WorkField++; }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
Hidden base class members can still be accessed from client code by casting the instance of the derived class to an instance of the base class. For example:
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Calls the old method.
Preventing Derived Classes from Overriding Virtual Members
Virtual members remain virtual indefinitely, regardless of how many classes have been declared between the virtual member and the class that originally declared it. If class A declares a virtual member, and class B derives from A, and class C derives from B, class C inherits the virtual member, and has the option to override it, regardless of whether class B declared an override for that member. The following code provides an example:
public class A
{
public virtual void DoWork() { }
}
public class B : A
{
public override void DoWork() { }
}
A derived class can stop virtual inheritance by declaring an override as sealed. This requires putting the sealed keyword before the override keyword in the class member declaration. The following code provides an example:
public class C : B
{
public sealed override void DoWork() { }
}
In the previous example, the method DoWork is no longer virtual to any class derived from C. It is still virtual for instances of C, even if they are cast to type B or type A. Sealed methods can be replaced by derived classes by using the new keyword, as the following example shows:
public class D : C
{
public new void DoWork() { }
}
In this case, if DoWork is called on D using a variable of type D, the new DoWork is called. If a variable of type C, B, or A is used to access an instance of D, a call to DoWork will follow the rules of virtual inheritance, routing those calls to the implementation of DoWork on class C.
well, you got it right. If it's not virtual, it gets hidden.
The new keyword brakes the virtual overriding in the inheritance hierarchy chain.
Simple example to read: Polymorphism, Method Hiding and Overriding in C#
Related
Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class(possibly by casting it back to the Derived class since you know it was originally a Derived class)
public class MySystem
{
public string name;
MySystem(string name)
{
this.name = name;
}
public void Update()
{
//dostuff
}
}
public class PowerSystem : MySystem
{
public int totalPower;
PowerSystem (string name, int power) : base(name)
{
this.totalPower = power;
}
public void Update()
{
base.Update();
//Do other stuff
}
}
void Main()
{
List<MySystem> SystemList = new List<MySystem>();
SystemList.Add(new System("Shields"));
SystemList.Add(new System("Hull"));
Power p = new Power("Power", 10);
SystemList.Add(p);
foreach(MainSystems ms in SystemList)
{
if(ms.name != "Power")
ms.Update();
else
(PowerSystem)ms.Update(); //This doesn't work
}
}
So what I'm trying to do is run the update method for every element in the list, with the exeption of the one I named power and instead run the Power.Update method.
The closest post I have found to answering this is here unfortunately I don't fully understand it.
I'm hoping that the list is holding a reference to PowerSystem p and that somehow I can convert it and access the PowerSystem menthod.
I hope this is clear.
Thanks
PS if you have a better idea for this I'm all ears.
Use polymorphism - mark Update in base class virtual and override it in derived class.
Base classes may define and implement virtual methods, and derived
classes can override them, which means they provide their own
definition and implementation. At run-time, when client code calls the
method, the CLR looks up the run-time type of the object, and invokes
that override of the virtual method. Thus in your source code you can
call a method on a base class, and cause a derived class's version of
the method to be executed.
public class MySystem
{
public string name;
MySystem(string name)
{
this.name = name;
}
public virtual void Update()
{
//dostuff
}
}
public class PowerSystem : MySystem
{
public int totalPower;
PowerSystem (string name, int power) : base(name)
{
this.totalPower = power;
}
public override void Update()
{
base.Update();
//Do other stuff
}
}
Now, PowerSystem.Update() will get called automatically
foreach(MainSystems ms in SystemList)
{
ms.Update();
}
For MySystem instances it will call MySystem.Update, but for PowerSystem instances the override will be called.
Consider these variants:
class A
{
public virtual void Doit()
{
}
}
class B : A
{
public new virtual void Doit()
{
}
}
or
class B : A
{
public override virtual void Doit()
{
}
}
I cannot find the difference in the returned results of the call typeof(B).GetMethod("Doit");
In both cases MethodInfo.DecalringType is class B and other properties seem the same.
Do I miss something or there is no way to distinguish them?
Update:
When I ran the sample in LINQPAd I noticed slight difference in Attributes property:
for new virtual value was - PrivateScope, Public, Virtual, HideBySig, VtableLayoutMask
for override - PrivateScope, Public, Virtual, HideBySig
Update 2:
I googled about VtableLayoutMask and came back to StackOverflow
Udate 3:
resulting code:
public static class MethodInfoExtensions
{
public static bool IsOverriden(this MethodInfo method)
{
Contract.Requires<ArgumentNullException>(method != null, "method");
return method.IsVirtual
&& !method.IsStatic
// overriden exactly in this class
&& method.ReflectedType == method.DeclaringType
// not new and not declared for the first time in the class
&& method.GetBaseDefinition() != method;
}
}
Update: The documentation seems to imply that IsHideBySig is the answer, but it does not appear to be the case in practice.
Another strategy is to rely on the presence of the NewSlot attribute:
public static bool HasNewModifier(this MethodInfo method)
{
return (method.Attributes & MethodAttributes.VtableLayoutMask)
== MethodAttributes.NewSlot;
}
Original, incorrect answer follows.
You can rely on the IsHideBySig property. It will be true if the method has the new modifier.
Note the above only applies to C# methods. The documentation elaborates with:
When a member in a derived class is declared with the C# new modifier
or the Visual Basic Shadows modifier, it can hide a member of the same
name in the base class. C# hides base class members by signature. That
is, if the base class member has multiple overloads, the only one that
is hidden is the one that has the identical signature. By contrast,
Visual Basic hides all the base class overloads. Thus, IsHideBySig
returns false on a member declared with the Visual Basic Shadows
modifier, and true on a member declared with the C# new modifier.
The DeclaringType will be different if it was hidden with new. For example, run:
public class A
{
public virtual void WillBeInheritted()
{
}
public virtual void WillBeOverridden()
{
}
public virtual void WillBeHidden()
{
}
}
public class B : A
{
public override void WillBeOverridden()
{
}
public virtual new void WillBeHidden()
{
}
}
class Program
{
public static void Main(string[] args)
{
foreach(var meth in typeof(B).GetMethods())
{
Console.Write(meth.Name);
Console.Write(": ");
Console.Write(meth.GetBaseDefinition().DeclaringType.Name);
Console.Write(" ");
Console.WriteLine(meth.DeclaringType.Name);
}
Console.Read();
}
}
The output will be:
WillBeOverridden: A B
WillBeHidden: B B
WillBeInheritted: A A
WillBeHidden: A A
ToString: Object Object
Equals: Object Object
GetHashCode: Object Object
GetType: Object Object
WillBeInheritted has A as the declaring type for both the method and the base definition's declaring type.
WillBeOverridden has A for the base definition's declaring type, B for the declaring type.
WillBeHidden has two versions, the hidden one in A and the hiding one in B. This makes sense when we consider:
B b = new B();
A a = b;
b.WillBeHidden(); // calls hiding method.
a.WillBeHidden(); // calls hidden method on same object.
You can use GetBaseDefinition to find out where this method was first declared.
For example if you let var mi = typeof(B).GetMethod("Doit"); you can check if mi.GetBaseDefinition() == mi or if mi.GetBaseDefinition().DeclaringType == typeof(B) etc.
Here is an example:
class Animal : object
{
public virtual void M()
{
}
}
class Mammal : Animal
{
public override void M()
{
}
}
class Giraffe : Mammal
{
}
static class Test
{
internal static void Run()
{
var mi = typeof(Giraffe).GetMethod("M");
Console.WriteLine(mi.ReflectedType); // Giraffe
Console.WriteLine(mi.DeclaringType); // Mammal
Console.WriteLine(mi.GetBaseDefinition().DeclaringType); // Animal
}
}
The MethodInfo instance mi represents the override as inherited (unchanged) to Giraffe. And mi.GetBaseDefinition() fetches another MethodInfo which represents instead the method Animal.M which does not carry the override keyword in the C# source.
I've been given a .NET project to maintain. I was just browsing through the code and I noticed this on a property declaration:
public new string navUrl
{
get
{
return ...;
}
set
{
...
}
}
I was wondering what does the new modifier do to the property?
It hides the navUrl property of the base class. See new Modifier. As mentioned in that MSDN entry, you can access the "hidden" property with fully qualified names: BaseClass.navUrl. Abuse of either can result in massive confusion and possible insanity (i.e. broken code).
new is hiding the property.
It might be like this in your code:
class base1
{
public virtual string navUrl
{
get;
set;
}
}
class derived : base1
{
public new string navUrl
{
get;
set;
}
}
Here in the derived class, the navUrl property is hiding the base class property.
This is also documented here.
Code snippet from msdn.
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
DerivedClass B = new DerivedClass();
B.WorkProperty; // Calls the new property.
BaseClass A = (BaseClass)B;
A.WorkProperty; // Calls the old property.
Some times referred to as Shadowing or method hiding; The method called depends on the type of the reference at the point the call is made. This might help.
https://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Look at the first example here, it gives a pretty good idea of how the new keyword can be used to mask base class variables
In the following example I am able to create a virtual method Show() in the inherited class and then override it in the inheriting class.
I want to do the same thing with the protected class variable prefix but I get the error:
The modifier 'virtual' is not valid
for this item
But since I can't define this variable as virtual/override in my classes, I get the compiler warning:
TestOverride234355.SecondaryTransaction.prefix'
hides inherited member
'TestOverride234355.Transaction.prefix'.
Use the new keyword if hiding was
intended.
Luckily when I add the new keyword everything works fine, which is ok since I get the same functionality, but this raises two questions:
Why I can use virtual/override for methods but not for protected class variables?
What is the difference actually between the virtual/override approach and the hide-it-with-new approach since at least in this example they offer the same functionality?
Code:
using System;
namespace TestOverride234355
{
public class Program
{
static void Main(string[] args)
{
Transaction st1 = new Transaction { Name = "name1", State = "state1" };
SecondaryTransaction st2 =
new SecondaryTransaction { Name = "name1", State = "state1" };
Console.WriteLine(st1.Show());
Console.WriteLine(st2.Show());
Console.ReadLine();
}
}
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
protected new string prefix = "Secondary";
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
}
Overriding a field does not really make sense. It's part of the state of the base class, and if an inheriting class wishes to change it, it should be changable in the inheriting class by giving it an appropriate visibility.
One thing you could do in your case is to set prefix in the constructor for the inheriting class:
// Base class field declaration and constructor
protected string prefix;
public Transaction()
{
prefix = "Primary";
}
// Child class constructor
public SecondaryTransaction()
{
prefix = "Secondary";
}
You can also make a property instead of a field, and make the property virtual. This will enable you to change the behavior of the getter and setter for the property in the inheriting class:
// Base class
public virtual string Prefix { get { /* ... */ } set { /* ... */ } }
// Child class
public override string Prefix { get { /* ... */ } set { /* ... */ } }
EDIT: As for your question of using a variable in a base constructor before an inheriting class has set it, one way to solve this is to define an initialization method in the base class, override it in the inheriting class, and call it from the base constructor before accessing any fields:
// Base class
public class Base
{
protected string prefix;
public Base()
{
Initialize();
Console.WriteLine(prefix);
}
protected virtual void Initialize()
{
prefix = "Primary";
}
}
// Inheriting class
public class Child : Base
{
public override void Initialize()
{
prefix = "Secondary";
}
}
EDIT 2: You also asked what the difference between virtual/override and name hiding (the new keyword on methods) is, if it should be avoided, and if it can be useful.
Name hiding is a feature that breaks inheritance in the case of hiding virtual methods. I.e., if you hide the Initialize() method in the child class, the base class will not see it, and not call it. Also, if the Initialize() method was public, external code that was calling Initialize() on a reference of the base type would be calling Initialize() on the base type.
Name hiding is useful when a method is non-virtual in a base class, and a child wants to provide a different implementation of its own. Note, however, that this is NOT the same as virtual/override. References of the base type will call the base type implementation, and references of the child type will call the child type implementation.
A static or non-virtual method or property is just a memory address (to simplify things). A virtual method or property is identified by an entry in a table. This table is dependent on the class defining the method or property.
When you override a virtual member in a derived class, you actually change the entry in the table for the derived class to point to the overriding method.
At run-time, access to such a member goes though the table, always. So the entry can be overridden by any derived class.
There is no such mechanism for fields, as they're meant to be accessed quickly.
Using 'new' on a member means that you do not want to override the entry in the table, but that you want a new member (with the same name as an existing virtual one, a bad practice if you ask me).
If you access a virtual member through a pointer to the base class, you'll never access the member defined as 'new' in the derived class, which is the difference mentioned in the second part of your question.
Rather create a property for the prefix member - this way you can set the property to virtual/abstract
Fields are used to store state for an object, they help the object encapsulate data and hide implementation concerns from others. By being able to override a field we are leaking the implementation concerns of the class to client code (including subtypes). Due to this most languages have taken the decision that one cannot define instance variables that can be overridden (although they can be public/protected... so you can access them).
You also cannot put instance variables in an interface
In your example, if you didn't override "Show" in the SecondaryTransaction class, then calling Show on an instance of SecondaryTransaction would actually be calling the method in the base class (Transaction), which would therefore use "Show" in the base class, resulting in output of:
Primary: name1, state1
Primary: name1, state1
So, depending on what method you were calling (i.e. one on the base class or the child class), the code would have a different value for "prefix" which would be a maintainability nightmare. I suspect what you probably want to/should do, is expose a property on Transaction that wraps "prefix".
You can't override a field because it's an implementation detail of the base class. You can change the value of a protected field, but by overriding it you'd essentially be saying I want to replace the field, not the value.
What I would do (if I absolutely didn't want to/couldn't use properties) :
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
public SecondaryTransaction()
{
prefix = "Secondary";
}
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
Edit: (As per my comment on another answer)
If you're calling down into your base class's ctor and need the value set, then you'll probably have to modify Transaction, possibly like this:
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
// Declared as virtual ratther than abstract to avoid having to implement "TransactionBase"
protected virtual void Initialise()
{ }
public Transaction()
{
Initialise();
}
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
protected override void Initialise()
{
prefix = "Secondary";
}
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
Why do you want to override a protected variable, surely all you want to do is set it to something else in the overriding class (possibly in the constructor)?
Overriding a field is a nonsense. Marking field as protected you automatically may access them in derived classes. You may override functions, properties, because it uses functions internally.
You can't because there is no use. What would you accomplish by overriding a field?
Simple:
class Animal{
public class Head {
int eye = 8;
}
Head head = new Head()
public void Test()
{
print head.eye;
DoOtherStufs();
} //8
protected virtual void DoOtherStufs()
{}
}
class Cat : Animal{
class new Head : Animal.Head
{
int mouth;
}
Head head = new Head()
protected override void DoOtherStufs()
{
print head.eye;
}
}
Cat cat = new Cat();
cat.head.eye = 9;
print cat.Test()
This will print 8 9 instead of 9 9 as expected.
I need a base class functional, but I also need a inherited class with I could manipulate (increase) the vars inside internal group classes vars. Its not possible!!
// Cannot change source code
class Base
{
public virtual void Say()
{
Console.WriteLine("Called from Base.");
}
}
// Cannot change source code
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
class Program
{
static void Main(string[] args)
{
SpecialDerived sd = new SpecialDerived();
sd.Say();
}
}
The result is:
Called from Special Derived.
Called from Derived. /* this is not expected */
Called from Base.
How can I rewrite SpecialDerived class so that middle class "Derived"'s method is not called?
UPDATE:
The reason why I want to inherit from Derived instead of Base is Derived class contains a lot of other implementations. Since I can't do base.base.method() here, I guess the best way is to do the following?
// Cannot change source code
class Derived : Base
{
public override void Say()
{
CustomSay();
base.Say();
}
protected virtual void CustomSay()
{
Console.WriteLine("Called from Derived.");
}
}
class SpecialDerived : Derived
{
/*
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
*/
protected override void CustomSay()
{
Console.WriteLine("Called from Special Derived.");
}
}
Just want to add this here, since people still return to this question even after many time. Of course it's bad practice, but it's still possible (in principle) to do what author wants with:
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
var ptr = typeof(Base).GetMethod("Say").MethodHandle.GetFunctionPointer();
var baseSay = (Action)Activator.CreateInstance(typeof(Action), this, ptr);
baseSay();
}
}
This is a bad programming practice, and not allowed in C#. It's a bad programming practice because
The details of the grandbase are implementation details of the base; you shouldn't be relying on them. The base class is providing an abstraction overtop of the grandbase; you should be using that abstraction, not building a bypass to avoid it.
To illustrate a specific example of the previous point: if allowed, this pattern would be yet another way of making code susceptible to brittle-base-class failures. Suppose C derives from B which derives from A. Code in C uses base.base to call a method of A. Then the author of B realizes that they have put too much gear in class B, and a better approach is to make intermediate class B2 that derives from A, and B derives from B2. After that change, code in C is calling a method in B2, not in A, because C's author made an assumption that the implementation details of B, namely, that its direct base class is A, would never change. Many design decisions in C# are to mitigate the likelihood of various kinds of brittle base failures; the decision to make base.base illegal entirely prevents this particular flavour of that failure pattern.
You derived from your base because you like what it does and want to reuse and extend it. If you don't like what it does and want to work around it rather than work with it, then why did you derive from it in the first place? Derive from the grandbase yourself if that's the functionality you want to use and extend.
The base might require certain invariants for security or semantic consistency purposes that are maintained by the details of how the base uses the methods of the grandbase. Allowing a derived class of the base to skip the code that maintains those invariants could put the base into an inconsistent, corrupted state.
You can't from C#. From IL, this is actually supported. You can do a non-virt call to any of your parent classes... but please don't. :)
The answer (which I know is not what you're looking for) is:
class SpecialDerived : Base
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
The truth is, you only have direct interaction with the class you inherit from. Think of that class as a layer - providing as much or as little of it or its parent's functionality as it desires to its derived classes.
EDIT:
Your edit works, but I think I would use something like this:
class Derived : Base
{
protected bool _useBaseSay = false;
public override void Say()
{
if(this._useBaseSay)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Of course, in a real implementation, you might do something more like this for extensibility and maintainability:
class Derived : Base
{
protected enum Mode
{
Standard,
BaseFunctionality,
Verbose
//etc
}
protected Mode Mode
{
get; set;
}
public override void Say()
{
if(this.Mode == Mode.BaseFunctionality)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Then, derived classes can control their parents' state appropriately.
Why not simply cast the child class to a specific parent class and invoke the specific implementation then? This is a special case situation and a special case solution should be used. You will have to use the new keyword in the children methods though.
public class SuperBase
{
public string Speak() { return "Blah in SuperBase"; }
}
public class Base : SuperBase
{
public new string Speak() { return "Blah in Base"; }
}
public class Child : Base
{
public new string Speak() { return "Blah in Child"; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Child childObj = new Child();
Console.WriteLine(childObj.Speak());
// casting the child to parent first and then calling Speak()
Console.WriteLine((childObj as Base).Speak());
Console.WriteLine((childObj as SuperBase).Speak());
}
}
public class A
{
public int i = 0;
internal virtual void test()
{
Console.WriteLine("A test");
}
}
public class B : A
{
public new int i = 1;
public new void test()
{
Console.WriteLine("B test");
}
}
public class C : B
{
public new int i = 2;
public new void test()
{
Console.WriteLine("C test - ");
(this as A).test();
}
}
You can also make a simple function in first level derived class, to call grand base function
My 2c for this is to implement the functionality you require to be called in a toolkit class and call that from wherever you need:
// Util.cs
static class Util
{
static void DoSomething( FooBase foo ) {}
}
// FooBase.cs
class FooBase
{
virtual void Do() { Util.DoSomething( this ); }
}
// FooDerived.cs
class FooDerived : FooBase
{
override void Do() { ... }
}
// FooDerived2.cs
class FooDerived2 : FooDerived
{
override void Do() { Util.DoSomething( this ); }
}
This does require some thought as to access privilege, you may need to add some internal accessor methods to facilitate the functionality.
In cases where you do not have access to the derived class source, but need all the source of the derived class besides the current method, then I would recommended you should also do a derived class and call the implementation of the derived class.
Here is an example:
//No access to the source of the following classes
public class Base
{
public virtual void method1(){ Console.WriteLine("In Base");}
}
public class Derived : Base
{
public override void method1(){ Console.WriteLine("In Derived");}
public void method2(){ Console.WriteLine("Some important method in Derived");}
}
//Here should go your classes
//First do your own derived class
public class MyDerived : Base
{
}
//Then derive from the derived class
//and call the bass class implementation via your derived class
public class specialDerived : Derived
{
public override void method1()
{
MyDerived md = new MyDerived();
//This is actually the base.base class implementation
MyDerived.method1();
}
}
As can be seen from previous posts, one can argue that if class functionality needs to be circumvented then something is wrong in the class architecture. That might be true, but one cannot always restructure or refactor the class structure on a large mature project. The various levels of change management might be one problem, but to keep existing functionality operating the same after refactoring is not always a trivial task, especially if time constraints apply. On a mature project it can be quite an undertaking to keep various regression tests from passing after a code restructure; there are often obscure "oddities" that show up.
We had a similar problem in some cases inherited functionality should not execute (or should perform something else). The approach we followed below, was to put the base code that need to be excluded in a separate virtual function. This function can then be overridden in the derived class and the functionality excluded or altered. In this example "Text 2" can be prevented from output in the derived class.
public class Base
{
public virtual void Foo()
{
Console.WriteLine("Hello from Base");
}
}
public class Derived : Base
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Text 1");
WriteText2Func();
Console.WriteLine("Text 3");
}
protected virtual void WriteText2Func()
{
Console.WriteLine("Text 2");
}
}
public class Special : Derived
{
public override void WriteText2Func()
{
//WriteText2Func will write nothing when
//method Foo is called from class Special.
//Also it can be modified to do something else.
}
}
There seems to be a lot of these questions surrounding inheriting a member method from a Grandparent Class, overriding it in a second Class, then calling its method again from a Grandchild Class. Why not just inherit the grandparent's members down to the grandchildren?
class A
{
private string mystring = "A";
public string Method1()
{
return mystring;
}
}
class B : A
{
// this inherits Method1() naturally
}
class C : B
{
// this inherits Method1() naturally
}
string newstring = "";
A a = new A();
B b = new B();
C c = new C();
newstring = a.Method1();// returns "A"
newstring = b.Method1();// returns "A"
newstring = c.Method1();// returns "A"
Seems simple....the grandchild inherits the grandparents method here. Think about it.....that's how "Object" and its members like ToString() are inherited down to all classes in C#. I'm thinking Microsoft has not done a good job of explaining basic inheritance. There is too much focus on polymorphism and implementation. When I dig through their documentation there are no examples of this very basic idea. :(
I had the same problem as the OP, where I only wanted to override a single method in the middle Class, leaving all other methods alone. My scenario was:
Class A - base class, DB access, uneditable.
Class B : A - "record type" specific functionality (editable, but only if backward compatible).
Class C : B - one particular field for one particular client.
I did very similar to the second part of the OP posting, except I put the base call into it's own method, which I called from from Say() method.
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
BaseSay();
}
protected virtual void BaseSay()
{
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.BaseSay();
}
}
You could repeat this ad infinitum, giving, for example SpecialDerived a BaseBaseSay() method if you needed an ExtraSpecialDerived override to the SpecialDerived.
The best part of this is that if the Derived changes its inheritance from Base to Base2, all other overrides follow suit without needing changes.
If you want to access to base class data you must use "this" keyword or you use this keyword as reference for class.
namespace thiskeyword
{
class Program
{
static void Main(string[] args)
{
I i = new I();
int res = i.m1();
Console.WriteLine(res);
Console.ReadLine();
}
}
public class E
{
new public int x = 3;
}
public class F:E
{
new public int x = 5;
}
public class G:F
{
new public int x = 50;
}
public class H:G
{
new public int x = 20;
}
public class I:H
{
new public int x = 30;
public int m1()
{
// (this as <classname >) will use for accessing data to base class
int z = (this as I).x + base.x + (this as G).x + (this as F).x + (this as E).x; // base.x refer to H
return z;
}
}
}