I have read an article regarding the new keyword. It says it is used to hide methods. This is example they give:
using System;
namespace ConsoleApplication3
{
class SampleA
{
public void Show()
{
Console.WriteLine("Sample A Test Method");
}
}
class SampleB:SampleA
{
public void Show()
{
Console.WriteLine("Sample B Test Method");
}
}
class Program
{
static void Main(string[] args)
{
SampleA a = new SampleA();
SampleB b = new SampleB();
a.Show();
b.Show();
a = new SampleB();
a.Show();
Console.ReadLine();
}
}
}
Output:
Sample A Test Method
Sample B Test Method
Sample A Test Method
So my question isn't the new keyword used to instantiated an object? and its used to allocate memory for new created objects? Then how can method hiding be done using it? And is above example correct?
new is used for 3 different things. You could say there are 3 different keywords with the same name.
It's an operator, used to invoke constructors. Example: new object();
It's a modifier, used to hide an inherited member from a base class member. Example:
class Base {
public void MyMethod() {
//Do stuff
}
}
class Derived : Base {
public new void MyMethod() {
//Do other stuff
}
}
It's a generic type constraint, used to indicate that a generic type parameter has a parameterless constructor. Example:
class MyGenericClass<T> : where T : new() { ... }
Source: new
Isn't the new keyword used to instantiated an object?
Yes it is. Among other things.
then how can method hiding done using it?
The new keyword in the context of method and property definitions has another meaning than the new keyword used to instantiate objects. The new keyword in that context tells that there is a new start of the inheritance tree of that particular method or property. That's all.
Then how can method hiding be done using it? And is above example
correct?
Programming language syntax, grammar and semantics are just an arbitrary set of conventions and specifications. That is, C# can invent one, two or dozen of usages of a given keyword like new.
When new is used during a class member declaration, it means that you're re-using an identifier:
public class A
{
public string Text { get; set; }
}
public class B : A
{
new public int Text { get; set; }
}
As you can check in above code sample, B also implements a Text property, but since derives from A which has also defined a Text property, there's a naming collision.
The so-called new keyword can be used to re-use Text identifier and being able to implement another property Text which may behave absolutely different than the one implemented in the base class. See that Text on B is of type int!
The most important point here is that re-using identifiers isn't the same as using polymorphism, where a class method or property override must match base class' member signature:
public class A
{
public virtual string Text { get; set; }
}
public class B : A
{
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
}
Also, re-used identifiers are dangerous:
public class A
{
public string Text { get; set; }
}
public class B : A
{
new public int Text { get; set; }
}
B b = new B();
b.Text = 4;
// Upcast B to A
A a = b;
a.Text = "Bye bye";
Console.WriteLine(a.Text); // Output: Bye bye
Console.WriteLine(b.Text); // Output: 4
See the output of Text. Since re-using identifiers isn't polymorphism, and in above case both are completely different properties, there's an A.Text and B.Text that can be set separately.
To hide an inherited member, declare it in the derived class by using the same member name, and modify it with the new keyword. For example:
public class BaseC
{
public static int x = 55;
public static int y = 22;
}
public class DerivedC : BaseC
{
// Hide field 'x'.
new public static int x = 100;
static void Main()
{
// Display the new value of x:
Console.WriteLine(x);
// Display the hidden value of x:
Console.WriteLine(BaseC.x);
// Display the unhidden member y:
Console.WriteLine(y);
}
}
/*
Output:
100
55
22
*/
You can read more in here
Related
I've been baffled by a behavior of new keyword in C#, as it doesn't seem to completely override its parent value, here's an example:
public static void Main(string[] args)
{
A test = new B();
Console.WriteLine(test.s);
}
public class A {
public string s = "A";
}
public class B : A{
public new string s = "B";
}
Now here I expected "B" to be printed, but instead, I got "A"
How can I always call the new property, whatever class is renewing it, instead of the original one?
The new keyword basically hides the member under a new member of the same name. However, this new member with the same name only exists on the subclass B and not on the base class A. So you wouldn't observe that test.s contains "B" unless you casted test to B first.
public static void Main(string[] args)
{
A test = new B();
Console.WriteLine(test.s); // A
B test2 = test as B;
Console.WriteLine(test2.s); // B
}
public class A
{
public string s = "A";
}
public class B : A
{
public new string s = "B";
}
If you want the member to be replaced, then you have to use the override keyword. However, you cannot override fields, only methods and properties. Try this:
public class A
{
protected virtual string s { get => "A"; }
}
public class B : A
{
protected override string s { get => "B"; }
}
public static void Main(string[] args)
{
A test = new B();
Console.WriteLine(test.s); // will print B
}
The virtual keyword on A.s indicates that that property can be overridden.
Julo's comment correctly points out that it is bad form to try to modify fields from subclasses anyway. Generally, class fields should always be private.
For methods and properties, you can do this by replacing new with override. override actually overrides the method, while new only hides it.
The same goes for fields, but you can't use override with fields.
But if you look closely, what you want here is to override the initial value of s. In both classes, s can be changed later on.
To change the initial value, just write a constructor:
public B() {
s = "B";
}
As it's already been pointed out, the new keyword is only going to hide the value, not override it. To do that, you'd need to use the override keyword, which can't be used on fields, but it can be used on properties, like this:
public static Main(string[] args)
{
A test = new B();
Console.WriteLine(test.S); // Prints "B"
}
public class A
{
protected string s;
public virtual string S { get => "A"; set => s = value; }
}
public class B : A
{
public override string S { get => "B"; set => s = value; }
}
This is probably the closest to what you expected to happen, but we have to introduce the backing field to be able to change the value of S. If you don't plan on doing so, you can just use public virtual string S => "A"; and making it a readonly.
However, this probably isn't the intended use of overriding properties. It's most likely there to do something different in the get or set functions like this:
public class A
{
public virtual string S
{
// Do Something
}
}
public class B : A
{
public override string S
{
// Do something else
}
}
Since all you're doing is changing the values, it's probably better to just do it in the constructor.
public class A
{
public string S { get; set; } = "A";
}
public class B : A
{
public B() => S = "B";
}
The downside of using the constructor is that, if you're changing the value for all the child classes, you're not gonna be able to quickly tell what the value is without opening up the constructor, which might make it harder to find. So, all in all, it's gonna come down to personal preference on which approach you use.
There are two clarifications I need which I am trying to understand.
I see that, I can access the variable "i" using "base" keyword as well as using the object. Is there any difference of it? I think, creation of object is memory consuming and hence we use base keyword itself to call base class members in derived class?
When to use this.i and base .i and object.i?
class Program
{
public Program()
{
i = 20;
}
public readonly int i = 10;
}
class C : Program
{
public C() : base()
{
//base.i = 20;
}
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 20
Console.WriteLine(c.i);//prints 20
Console.WriteLine(this.i); //Also prints 20 :D
}
static void Main()
{
C c = new C();
c.Display();
Console.ReadLine();
}
I tried to accept one answer as that helped me understand few things. But still, my question "the difference ans usage of 3 different styles at my context and in other contexts" is not clear. So please care to share your thoughts on this, I would appreciate it. I am sure there are millions like me who try to understand this :)
As for 1) You can use both to access the property as the sub class has extended it. There will only be a difference if you override that in the sub class or if you decide to create a field with the same name in your sub class.
EDIT:
To override it, you can make it a virtual property in the base class
public class Base
{
public virtual int i {get; set;}
}
public class Sub : Base
{
public override int i { get; set; }
}
Problem 2 : Your StackOverflow
you care creating a new instance of Program every time you create a new instance of Program it seems to be an infinite loop.
class Program
{
Program p = new Program(); // <-- this line here
In your case there is no difference. Difference comes when you have field with same name in base class and derived class(typically we don't have it).
class Program
{
public int i = 10;
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 10
Console.WriteLine(c.i);//prints 20
}
}
base keyword refers to base class, so base.i refers to "member named i" in base class.
Also worth noting that when you access a member with base keyword and it doesn't exist compiler will produce an error.
class Program
{
//public int i = 10; //No field named i
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//Compile time error here
Console.WriteLine(c.i);//this refers to C.i field
}
}
Answer for Question 1
Base you can use when you want to refer you prent class from the child class.
Example :
public class A
{
public int i {get;set;}
}
public class B:A
{
publi void readvalueofi()
{ Console.Writeln(base.i); }
}
This also useful when you override method of parent and want to call parent method from child
Example :
public class Parent
{
public virtual void Print()
{
Console.WriteLine("Print in Parent");
}
}
public class Child : Parent
{
public override void Print()
{
base.Print();
Console.WriteLine("Print in Child");
}
}
Answer for Question 2 :
Reason for StackOverflow Exception
You're creating an private instance of Program when Program is created so this is sort of an endless loop:
your first create Program instance. When this instance is creating it creates a new instance of Program. This instance also creates an instance of Programand again, and again etc.
So basially it creates infinite loop over here.
This question already has answers here:
new keyword in method signature
(9 answers)
Closed 9 years ago.
I have seen methods that are declared like this:
public void new SortItems()
What does this actually do? I know that the new keyword is used to invoke constructors, but I have also seen it on method definitions like the example above.
When use this way, it's a modifier. It's used to hide an inherited member rather than to override it. This is useful if the base method is sealed. Here's a quick example to demonstrate the difference between overriding and hiding inherited members:
public class Foo
{
public virtual void OverriddenMethod() { Console.WriteLine("foo"); }
public void HiddenMethod() { Console.WriteLine("foo"); }
}
public class Bar : Foo
{
public override void OverriddenMethod() { Console.WriteLine("bar"); }
public new void HiddenMethod() { Console.WriteLine("bar"); }
}
void Main()
{
Bar bar = new Bar();
Foo foo = bar;
bar.OverriddenMethod(); // "bar"
bar.HiddenMethod(); // "bar"
foo.OverriddenMethod(); // "bar"
foo.HiddenMethod(); // "foo"
}
Further Reading
new Modifier (C# Reference)
It should be like this:
public new void SortItems(){
//...
}
This new keyword is used to shadow the base member (method, property, ...) which has the same name (for property, event...) and same signature (for method), in this case it is the method SortItems. It's different from the new in creating new instance. No matter using new to shadow the conflicted member in base class or not, to access the base member you have to use the keyword base to access it in the derived class.
When used in a method signature, it means that the implementation details are different for the class defining them. The problem with this approach is that it is not used polymorphically so:
class Thing
{
void DoSomething()
{
Console.WriteLine("Thing");
}
}
class Other : Thing
{
new void DoSomething()
{
Console.WriteLine("Other");
}
}
var thing = new Thing();
thing.DoSomething(); \\ prints Thing
var other = new Other();
other.DoSomething(); \\ prints Other
((Thing)other).DoSomething(); \\ prints Thing
It is the opposite of override. Say you have:
public class A
{
public virtual void f() { Console.WriteLine( "A" ); }
}
public class B : A
{
public override void f() { Console.WriteLine( "B" ); }
}
public class C : A
{
public new void f() { Console.WriteLine( "C" ); }
}
And then in main:
A b = new B();
A c = new C();
b.f();
c.f();
(c as C).f();
This would print:
B
A
C
It will only call the new method when the type is that of the defining class.
Consider the following very basic C# code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
for (int i = 1; i <= 100; i++)
{
int num = random.Next(1000);
string it_type;
if (num == 666)
{
System.Console.Write("Antichrist/satanistic trips get. Enjoy! ");
JonSkeet technician = new JonSkeet(); // Needs more Super::$tatic
technician.setup();
it_type = technician.getITType();
}
else
{
Whisperity technician = new Whisperity();
technician.setup();
it_type = technician.getITType();
}
System.Console.WriteLine(it_type + "... Prepare for next iteration.");
}
System.Console.ReadLine();
}
}
abstract public class ITTechnician
{
protected string itt_type = "Noname person.";
protected bool isJonSkeet = false;
public string getITType()
{
return this.itt_type;
}
abstract public void setup();
}
public class JonSkeet : ITTechnician
{
public override void setup()
{
this.itt_type = "Jon Skeet";
this.isJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
public override void setup()
{
this.itt_type = "Whisperity";
this.isJonSkeet = false;
}
}
}
How would I be able to set up a constructor in a way that the abstract class (abstract public void?) would require it and that I don't have to call technician.setup(); because the constructor takes care of setting the two internal variables. If I call the class functions the same name as the class itself, I get the following error:
Error 1 'Whisperity': member names cannot be the same as their enclosing
Also, my other question would be about optimization. Is there a way to define technician outside the if construct so something like the following could be executed: (This would omit having the classType technician = new classType(); lines twice, or is it unbypassable in C#?)
string it_type;
// Register 'technician' as a variable here.
if (num = 666)
{
technician = new JonSkeet();
}
else
{
technician = new Whisperity();
}
it_type = technician.getITType();
System.Console.WriteLine(it_type + "...");
Answer to your Question
You can provide a constructor with parameters in the abstract class.
abstract public class ITTechnician
{
public ITTechnician(string itt_type, bool isJonSkeet)
{
this.itt_type = itt_type;
this.isJonSkeet = isJonSkeet;
}
}
To construct a JonSkeet (if only it were so easy!)
JonSkeet jon = new JonSkeet("Jon Skeet", true);
Advice on Class Design
On a side note, I know this is a sample question, but you are not using object orientation well if a base class holds information that would differentiate classes that inherit from it.
Specifically this design would lead you to do things like
ITTechnician itt = GetSomeInstance();
if (itt.IsJonSkeet)
{
BehaviorA();
else
{
BehaviorB();
}
It is far cleaner to do something like
abstract public class ITTechnician
{
public abstract void Behavior();
// ...
}
public class JonSkeet
{
public override Behavior()
{
// Do awesome things
}
}
which allows the above code to be written as
ITTechnician itt = GetSomeInstance();
itt.Behavior();
How would I be able to set up a constructor in a way that the abstract
class would require it and that I don't have to call
technician.setup()
You don't need construct your logic to force the behavior of abstract class, but vice versa. Abstract class defines a stuf that has to be followed by the child.
If you create a simple parametless ctor in abstract class, which initializes the variables you need, whenever the child object will be constructed, the default ctor of abstract will be called before, so intialization will be executed.
To be more clear:
public class Child : Base
{
public Child(int x){
"Child".Dump();
}
}
public abstract class Base
{
public Base() {
//INIT VARIABLES HERE
"Base".Dump();
}
}
using these constructs like
vaar ch = new Child(); produces the result
"Base"
"Child"
If this is not what you're asking for, please clarify.
To discover a type at runtime, use GetType(). There's no need to create your own type string field.
The only thing that varies other than the intrinsic type in your class structure is IsJonSkeet. We can use a .NET property to implement this, which is a more modern and expressive way when compared to traditional private/protected fields with a Getter and maybe a Setter.
abstract public class ITTechnician
{
public bool IsJonSkeet { get; protected set; }
protected ITTechnician()
{
this.IsJonSkeet = false;
}
}
public class JonSkeet : ITTechnician
{
public JonSkeet()
{
this.IsJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
}
Now that your itt_type string field has been removed, Whisperity is the same as the base class, so there's no need for a constructor to do any initialisation - it will pick up the IsJonSkeet value of its parent automatically.
+1 for Eric J's class design tips, too. You should use the design of your hierarchy to encapsulate what varies and this makes your calling code much more transparent and the codebase easier to expand on in the future.
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