Is it alright in a hierarchy to use the new keyword at some point to override the return type in a method?
Can I use virtual new or new virtual so I can override the return type?
I need to consider also classes that inherit from that point on. Can they override this method where the base was created with new?
You can do this, but the real question is whether you should do it.
The problem is that you'll get very unexpected behavior, depending on how your class is used. If you're calling your class from an instance of the base class, the original, non-"new" method will get called, which will probably be unexpected.
In general, I'd avoid using the new keyword to override a base class method unless there is a very distinct reason to do so - if your method is going to return a new type, declare it as a new method with a different name or signature instead of hiding the base class method - it will make your hierarchy much more usable.
Hypothetically....
public class BaseCollection<T>
{
// void return - doesn't seem to care about notifying the
// client where the item was added; it has an IndexOf method
// the caller can use if wants that information
public virtual void Add(T item)
{
// adds the item somewhere, doesn't say where
}
public int IndexOf(T item)
{
// tells where the item is
}
}
public class List<T> : BaseCollection<T>
{
// here we have an Int32 return because our List is friendly
// and will tell the caller where the item was added
new public virtual int Add(T item) // <-- clearly not an override
{
base.Add(item);
return base.IndexOf(item);
}
}
Here I use the "new" modifier because a List<T> reference will hide the Add method from the BaseCollection<T>. By default, hiding members from a base generates a warning from the compiler (an error if you have compilation set up to fail on warnings). So I'm basically telling the compiler... "Yeah I know I hid the Add method with the void return, it's desired functionality - just go with it."
Related
Can anybody tell the working of overriding and hiding in terms of memory and references.
class A
{
public virtual void Test1() { //Impl 1}
public virtual void Test2() { //Impl 2}
}
class B : A
{
public override void Test1() { //Impl 3}
public new void Test2() { Impl 4}
}
static Main()
{
A aa=new B() //This will give memory to B
aa.Test1(); //What happens in terms of memory when this executes
aa.Test2(); //-----------------------SAME------------------------
}
Here memory is with class B but in the second statement aa.Test2 class A's method will be called. Why is it? If B has memory then B's method should be called (in my point of view).
Any link / exercise that describes this fundamental very deeply and completely will be a big help.
Take a look at this answer to a different question by Eric Lippert.
To paraphrase (to the limits of my comprehension), these methods go into "slots". A has two slots: one for Test1 and one for Test2.
Since A.Test1 is marked as virtual and B.Test1 is marked as override, B's implementation of Test1 does not create its own slot but overwrites A's implementation. Whether you treat an instance of B as a B or cast it to an A, the same implementation is in that slot, so you always get the result of B.Test1.
By contrast, since B.Test2 is marked new, it creates its own new slot. (As it would if it wasn't marked new but was given a different name.) A's implementation of Test2 is still "there" in its own slot; it's been hidden rather than overwritten. If you treat an instance of B as a B, you get B.Test2; if you cast it to an A, you can't see the new slot, and A.Test2 gets called.
To add to #Rawling's answer, practical examples could be shown using an example such as this:
class Base
{
// base property
public virtual string Name
{
get { return "Base"; }
}
}
class Overriden : Base
{
// overriden property
public override string Name
{
get { return "Overriden"; }
}
}
class New : Base
{
// new property, hides the base property
public new string Name
{
get { return "New"; }
}
}
1. Overriding
In case of the overriden property, base class' virtual method's slot is replaced by a different implementation. Compiler sees the method as virtual, and must resolve its implementation during run-time using the object's virtual table.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new Overriden();
// Base.Name is virtual, so the vtable determines its implementation
Console.WriteLine(b.Name); // prints "Overriden"
Overriden o = new Overriden();
// Overriden.Name is virtual, so the vtable determines its implementation
Console.WriteLine(o.Name); // prints "Overriden"
}
2. Hiding
When a method or a property is hidden using the new keyword, the compiler creates a new non-virtual method for the derived class only; base class' method remains untouched.
If the type of the variable is Base (i.e. only contains the virtual method), its implementation will be resolved through the vtable. If the type of the variable is New, then the non-virtual method or property will be invoked.
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new New();
// type of `b` variable is `Base`, and `Base.Name` is virtual,
// so compiler resolves its implementation through the virtual table
Console.WriteLine(b.Name); // prints "Base"
New n = new New();
// type of `n` variable is `New`, and `New.Name` is not virtual,
// so compiler sees `n.Name` as a completely different property
Console.WriteLine(n.Name); // prints "New"
}
3. Summary
If a part of your code accepts the base type, it will always use the virtual table during run-time. For most OOP scenarios, this means that marking a method as new is very similar to giving it a completely different name.
4. Object sizes after instantiation
Note that instantiating any of these types doesn't create a copy of the virtual table. Each .NET object has a couple of bytes of header and a pointer to the virtual table of table of its type (class).
Regarding the new property (the one which is not virtual), it is basically compiled as a static method with thiscall semantics, meaning that it also doesn't add anything to the size of the instance in memory.
Already answered at here
Overriding is the definition of multiple possible implementations of the same method signature, such that the implementation is determined by the runtime type of the zeroth argument (generally identified by the name this in C#).
Hiding is the definition of a method in a derived type with a signature identical to that in one of its base types without overriding.
The practical difference between overriding and hiding is as follows:
Hiding is for all other members (static methods , instance members, static members). It is based on the early binding . More clearly , the method or member to be called or used is decided during compile time.
•If a method is overridden, the implementation to call is based on the run-time type of the argument this.
•If a method is simply hidden, the implementation to call is based on the compile-time type of the argument this.
Here are some samples : Example # 1. and Example # 2
Test1() method in class A and test1() method in class B will executes according to MethdOverriding.
Test2() method in class A and test2() method in class B will executes according to Method Hiding.
In method Overriding the child class members will execute, and in Method Hiding the Parent class members will execute.
Put simply when overriding a method or property the override method must have the same signature as the base method. When hiding this is not required, the new object can take any form as shown below
// base
public int GrossAmount { get; set; }
// hiding base
public new string GrossAmount
{
get;
set;
}
Deducting from the code provided you should have B:A.
You can hide a method in case when you want create your own implementation of the (say) method of the base class, which can not be overriden, cause, say, it's not virtual.
In my expirience, I used hiding mostly for debug purposes.
For example when I don't know who sets the property of some 3rd prt component, whom code is not available to me. So what I do is:
create a child class from the component
hide the property of interest with new keyword
put the breakpoint in set
and wait when it will be hit.
Sometimes, very useful and helps me get information in fast way, especially in first stage when you're learning new components, frameworks, libraries.. whatever.
By hiding a method or a property you are simply stating that you want to stop such method being polymorphic when you have an object of that type. Additionally hidden methods are called in a non polymorphic way so to call these method type has to be know at compile time, as it was a simply non virtual method.
public class BaseClass
{
public void PrintMethod()
{
Console.WriteLine("Calling base class method");
}
}
public class ChildClass
{
public new void PrintMethod()
{
Console.WriteLine("Calling the child or derived class method");
}
}
class Program
{
static void Main()
{
BaseClass bc = new ChildClass();
bc.PrintMethod();
}
}
Method Hiding is that when Base Class reference variable pointing to a child class object. It will invoke the hidden method in base Class.
Where as, When We declare virtual method in the base class. We override that method in the derived or child class. Then Base Class reference variable will call the derived class method. This is called Method Overriding.
class Base {
int a;
public void Addition() {
Console.WriteLine("Addition Base");
}
public virtual void Multiply()
{
Console.WriteLine("Multiply Base");
}
public void Divide() {
Console.WriteLine("Divide Base");
}
}
class Child : Base
{
new public void Addition()
{
Console.WriteLine("Addition Child");
}
public override void Multiply()
{
Console.WriteLine("Multiply Child");
}
new public void Divide()
{
Console.WriteLine("Divide Child");
}
}
class Program
{
static void Main(string[] args)
{
Child c = new Child();
c.Addition();
c.Multiply();
c.Divide();
Base b = new Child();
b.Addition();
b.Multiply();
b.Divide();
b = new Base();
b.Addition();
b.Multiply();
b.Divide();
}
}
Output : -
Addition Child
Multiply Child
Divide Child
Addition Base
Multiply Child
Divide Base
Addition Base
Multiply Base
Divide Base
At the time of overriding the compiler checks the object of the class but in
in hiding compiler only checks the reference of the class
I have a BaseClass, which implements a method to populate itself form a different data structure. SubClasses will add their properties to the base ones. I want all sub-classes and sub-sub...classes to implement their own version of the method and call their parent class to do the same. So this is not just overriding, I want to force the implementation, but each implementation of the method has to be called, not just overridden.
Sort of like:
class BaseClass
{
int id;
virtual void fromDictionary(Dictionary data)
{
id = data["id"];
}
}
class Derived1 : BaseClass
{
string name;
override void fromDictionary(Dictionary data)
{
name = data["name"];
base.fromDictionary(data);
}
}
class Derived2 : Derived1
{
float size;
override void fromDictionary(Dictionary data)
{
size = data["size"];
base.fromDictionary(data);
}
}
Then doing this:
Derived2 object = new Derived2();
object.fromDictionary(dictionary);
Populates all of the object's properties.
I can make the first one virtual and override in the derived ones, but that doesn't force the implementation. And making an abstract base above this base or using an interface wouldn't force ALL levels of inheritance to implement.
The ideal case would be forcing all derived classes to implement their version AND call their parent's version (or even better, have some sort of extension/overriding that automatically calls ALL implementations of the method from the instantiated object's class upwards).
How close to that can I get ?
Seeing why you need this kind of overriding I strongly believe that you should try to move this logic to a constructor because as it looks now:
Derived2 object = new Derived2();
object.fromDictionary(dictionary);
Your object will only be valid if it has a dictionary. So instead of constructing it from a dictionary using a method, you should provide a constructor which receives a dictionary as a parameter:
Derived2 object = new Derived2(dictionary);
Now you have a valid object from the beggining. There are more reasons why you should do this instead of using a method which composes your object, one as you observed is that each subclass will need to call the base method, and having this kind of constructor (assuming that you will not provide a parameterless one) will force the inheritors to call the base one.
Another advantage in using this kind of approach is that you will have a valid object form the beginning instead of making it possible for users of that classes to make invalid objects by forgetting to call the fromDictionary() method.
Thanks for the suggestions everyone, the closest I could get is:
public abstract class DAO
{
public long id { get; set; }
public void fromDictionary(Dictionary<string, object> obj)
{
//Does own part in the method
id = (long)obj["id"];
//Calls most derived implementation
fromDictionaryOperation(obj);
}
//Forces child to implement its part
protected abstract void fromDictionaryOperation(Dictionary<string, object> obj);
}
//Is forced to implement its part, and the base implementation will be executed always
public class Area : DAO
{
public string name { get; set; }
protected override void fromDictionaryOperation(Dictionary<string, object> obj)
{
name = (string)obj["name"];
}
}
//Is NOT forced to implement method, and MUST call base.fromDictionary() for all this to work properly, but is NOT FORCED TO.
public class CircularArea : Area
{
public float radius { get; set; }
protected override void fromDictionaryOperation(Dictionary<string, object> obj)
{
radius = (float)obj["radius"];
base.fromDictionary(obj);
}
}
So all 2nd generation classes will be fine, but subsequent sub-classes wont be forced to implement its part or call the parent implementation. Which means that if in an implementation of a sub-sub-class, the base.fromDictionary() method is not called, then all parent classes implementation, except the first/base class, will be skipped without any compiling warning or error.
To force implementation at all levels, I guess I could put the abstract method in an Interface and make all classes implement the interface, which can't be forced itself, but is as close as I can think of.
If anyone knows a way to completely force ALL of them to implement the same method, that would be top notch.
I am trying to override a virtual function only for a single defined element (without having to create another class that implements it and then adding a function to override it..).
Example:
public class MyClass
{
public virtual bool ChangeStatus(String status)
{
return false;
}
}
void test()
{
//The following is written as an example of what I am trying to achieve & does not work
MyClass blah = new MyClass()
{
public override bool ChangeStatus(String status)
{
return true;
}
};
}
Any idea how to achieve this?
Thanks.
if you have control over MyClass, you can let the desired method call a delegate which can be replaced for every single object at runtime...
class MyClass
{
public void Func<SomeParameterType,SomeReturnType> myDelegate {get;set;}
public SomeReturnType myFunction(SomeParameterType parameter)
{
if(myDelegate==null)
throw new Exception();
return myDelegate(parameter);
}
}
...
MyClass obj = new MyClass();
SomeParameterType p = new SomeParameterType();
obj.myDelegate = (x)=>new SomeReturnType(x);
SomeReturnType result = obj.myFunction(p);
"virtual" and "override" both are related to INHERITANCE.
1.A virtual method can be redefined. The virtual keyword designates a method that is overridden in derived classes. We can add derived types without modifying the rest of the program. The runtime type of objects thus determines behavior.
2.When you want to allow a derived class to override a method of the base class, within the base class method must be created as virtual method and within the derived class method must be created using the keyword override.
You cannot override a function without inheriting the class, the whole point of a virtual function is that it can be overridden in the child class.
If your are doing it withing the same class, wouldn't you end up writing a simple method/function for the class ?
So, follow the OOP programming concept, it is designed for simplicity & ease of programming. Instead simply inherit the class and override the function
C# is strictly built on the concept of classes. You cannot create a function/method without a class.
Additionally, virtual/override implies inheritance, so you MUST derive from this class.
Here's the situation. I have a base class which implements a method that accepts a string, and sets a property to the value of that string. Under that, I have a group of concrete classes that implement the base. Some of the concrete classes can accept any string value to be stored. However, some of the class's values are constrained within an Enumerated series of values. The final value is still a string, but the value must be within that enumerated set of possible values.
Here's what I'd like to do: For the classes which use an enum-restricted value, I want to implement an overload to the string method that calls the string method with the correct value. However, I also want to lock the string implementation out so that only the enum implementation can be used to pass a new value in, in order to enforce the enum restriction.
I know at this point that this just isn't going to happen through the use of override or new in the method declaration. I also know that I could create a hierarchy like Base -> [BaseString|BaseEnum] -> Concrete and use sealing to keep the concrete implementation from allowing the string-based implementation to be used. What I'd like to know is if there's another way to do this that skips the extra level of hierarchy and allows me to just say "If method overload is present in concrete class, lock method."
public class Abstract {
public virtual string ValueHolder { get; private/protected set; }
public virtual void DoSomething( string s ) { ...; }
}
public class ConcreteEnum : Abstract {
public void DoSomething( Enum e ) {
base.DoSomething( "String somehow extracted from enum");
}
}
public class ConcreteString : Abstract { ... }
public class Main {
ConcreteString sc = new ConcreteString();
ConcreteEnum se = new ConcreteEnum();
sc.DoSomething( "I don't have an overload defined,
so I'm using my base's string handler method.
I can be any value, I have no restrictions." );
se.DoSomething( SomeEnum.MyValueWillBeRunThroughTheBaseStringHandler );
se.DoSomething( "I don't work because there's an
overload defined in my concrete class, and my
value is restricted to a specific set of
possibilities." );
}
As I said, I know that there are other viable ways of doing this, I just want to know if this is possible/more clean than those alternatives.
You would basically need to just validate the string in the derived class:
public class ConcreteEnum : Abstract {
public void DoSomething( Enum e ) {
base.DoSomething( "String somehow extracted from enum");
}
public override void DoSomething( string s ) {
// Validate s, then do something with it
}
}
You can't remove the method entirely, since it is a member of the superclass and hence part of the class interface. For example, if you passed an instance of ConcreteEnum to a method that takes an Abstract object and expected the DoSomething(string) method to work, but it was magically gone, all hell would break loose.
But you always have the option of overriding the behavior in a subclass to throw exceptions when an invalid value is supplied. You could even override it to just throw a NotSupportedException.
EDIT: If the base class DoSomething method is not supposed to be consumed except in subclasses (not saying it is, but you didn't really specify either way), why not just make it protected?
Being mainly a Java developer, I was a bit surprised by the result when I one day accidentally used new keyword instead of override.
It appears that the new keyword removes the "virtualness" of the method at that level in the inheritance tree, so that calling a method on an instance of child class that is downcasted to the parent class, will not resolve to the method implementation in the child class.
What are the practical use cases for this behavior?
Clarification: I understand the use of new when parent is not virtual. I'm more curious why the compiler allows new and virtual to be combined.
The following example illustrates the difference:
using System;
public class FooBar
{
public virtual void AAA()
{
Console.WriteLine("FooBar:AAA");
}
public virtual void CCC()
{
Console.WriteLine("FooBar:CCC");
}
}
public class Bar : FooBar
{
public new void AAA()
{
Console.WriteLine("Bar:AAA");
}
public override void CCC()
{
Console.WriteLine("Bar:CCC");
}
}
public class TestClass
{
public static void Main()
{
FooBar a = new Bar();
Bar b = new Bar();
Console.WriteLine("Calling FooBar:AAA");
a.AAA();
Console.WriteLine("Calling FooBar:CCC");
a.CCC();
Console.WriteLine("Calling Bar:AAA");
b.AAA();
Console.WriteLine("Calling Bar:CCC");
b.CCC();
Console.ReadLine();
}
}
This produces the following output:
Calling FooBar:AAA
FooBar:AAA
Calling FooBar:CCC
Bar:CCC
Calling Bar:AAA
Bar:AAA
Calling Bar:CCC
Bar:CCC
Use case:
Today, you use a 3rd party library and derive class Banana from class Fruit.
You implement a method called Peel in Banana. There is no Peel in Fruit.
Tomorrow, the 3rd party releases a new version of the library, including a virtual Fruit.Peel method
You recompile your code tomorrow. Do you want to override Fruit.Peel? Quite possibly not - it could have a completely different meaning. Instead, you hide it with Banana.Peel and all the existing code works as it does today.
In other words, it's mostly to avoid versioning issues. In Java, you'd end up overriding Fruit.peel even though you didn't want to, quite possibly leading to hard-to-diagnose bugs.
Speaking from personal experience, I mostly see the "new" keyword used in cases where the original parent method was not specified as virtual, but an override behavior was desired. Application of the "new" keyword "hides" the parent method. And, as you observed in the code example, the method written with "new" will only be executed when working directly with that type. If working with the parent type, the parents original method will be called.
To answer your question more directly - it provides a means of overriding methods when the parent method was not labeled virtual.
EDIT: As an aside, adding the "new" keyword to hide a parent method that is not naturally overrideable does not actually change anything in the generated IL. But it is a means of explicitly stating to the developer "Hey, you're hiding a parent method here, not overriding it"
Hypothetically....
public class BaseCollection<T>
{
// void return - doesn't seem to care about notifying the
// client where the item was added; it has an IndexOf method
// the caller can use if wants that information
public virtual void Add(T item)
{
// adds the item somewhere, doesn't say where
}
public int IndexOf(T item)
{
// tells where the item is
}
}
public class List<T> : BaseCollection<T>
{
// here we have an Int32 return because our List is friendly
// and will tell the caller where the item was added
new public virtual int Add(T item) // <-- clearly not an override
{
base.Add(item);
return base.IndexOf(item);
}
}
Here I use the "new" modifier because a List<T> reference will hide the Add method from the BaseCollection<T>. By default, hiding members from a base generates a warning from the compiler (an error if you have compilation set up to fail on warnings). So I'm basically telling the compiler... "Yeah I know I hid the Add method with the void return, it's desired functionality - just go with it."