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
Related
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
I want to hide the base public property(a data member) in my derived class:
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class a
{
public int item1 {get; set;}
public int item2 { get; set; }
}
class b : a
{
new private int item1;
}
class c : a
{
}
i have member as public because i want the member to be inherited in c class , but want to hide the member in b class , how can i do this ?
dont i have an option to selectively inherite the variable i want in my base class ??? thats really bad , i think ms should provide us with an option (may be a modifier) to perform this
Edit:
I found the answer myself (i heard lots of them telling this is not possible in c#, but you can kind of do it)
I am including the code in case it is useful
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4; // shows an error : )
}
}
class a
{
public int item1 { get; set; }
public int item2 { get; set; }
}
class b : a
{
new public static int item1
{
get;
private set;
}
}
I'm going to attempt to explain with examples why this is a bad idea, rather than using cryptic terms.
Your proposal would be to have code that looks like this:
public class Base
{
public int Item1 { get; set; }
public int Item2 { get; set; }
}
public class WithHidden : Base
{
hide Item1; // Assuming some new feature "hide" in C#
}
public class WithoutHidden : Base { }
This would then make the following code invalid:
WithHidden a = new WithHidden();
a.Item1 = 10; // Invalid - cannot access property Item1
int i = a.Item1; // Invalid - cannot access property Item1
And that would be just what you wanted. However, suppose we now have the following code:
Base withHidden = new WithHidden();
Base withoutHidden = new WithoutHidden();
SetItem1(withHidden);
SetItem1(withoutHidden);
public void SetItem1(Base base)
{
base.Item1 = 10;
}
The compiler doesn't know what runtime type the argument base in SetItem1 will be, only that it is at least of type Base (or some type derived from Base, but it can't tell which -- it may be obvious looking at the code snippet, but more complex scenarios make it practically impossible).
So the compiler will not, in a large percentage of the cases, be able to give a compiler error that Item1 is in fact inaccessible. So that leaves the possibility of a runtime check. When you try and set Item1 on an object which is in fact of type WithHidden it would throw an exception.
Now accessing any member, any property on any non-sealed class (which is most of them) may throw an exception because it was actually a derived class which hid the member. Any library which exposes any non-sealed types would have to write defensive code when accessing any member just because someone may have hidden it.
A potential solution to this is to write the feature such that only members which declare themselves hideable can be hidden. The compiler would then disallow any access to the hidden member on variables of that type (compile time), and also include runtime checks so that a FieldAccessException is thrown if it is cast to the base type and tried to be accessed from that (runtime).
But even if the C# developers did go to the huge trouble and expense of this feature (remember, features are expensive, especially in language design) defensive code still has to be written to avoid the problems of potential FieldAccessExceptions being thrown, so what advantage over reorganising your inheritance hierarchy have you gained? With the new member hiding feature there would be a huge number of potential places for bugs to creep into your application and libraries, increasing development and testing time.
What you want to do goes directly against the grain of OO, you can't 'unpublish' members as this violates the substitution principle. You have to refactor this into something else.
Vadim's response reminded me of how MS achieve this in the Framework in certain places. The general strategy is to hide the member from Intellisense using the EditorBrowsable attribute. (N.B. This only hides it if it is in another assembly) Whilst it does not stop anyone from using the attribute, and they can see it if they cast to the base type (see my previous explination) it makes it far less discoverable as it doesn't appear in Intellisense and keeps the interface of the class clean.
It should be used sparingly though, only when other options like restructuring the inheritance hierarchy would make it a lot more complex. It's a last resort rather than the first solution to think of.
If you use an interface instead of a base class for defining the property, you could implement the property explicitly. The would require an explicit cast to the interface to use the property.
public interface IMyInterface
{
string Name { get; set; }
}
public class MyClass : IMyInterface
{
string IMyInterface.Name { get; set; }
}
You can find more out here.
The only thing I can think of is to make item1 virtual in class a:
class a
{
public virtual int item1 { get; set; }
public int item2 { get; set; }
}
and then override it in class b but throw an exception in getter and setter. Also if this property is used in a visual designer you can use Browsable attribute to not display.
class b : a
{
[Browsable(false)]
public override int item1
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
}
First of all this is not good idea if you using some methods, that operates base class.
You can try to use obsolete argument to make users twice think to use this property.
[System.Obsolete("Do not use this property",true)]
public override YourType YourProperty { get; set; }
What you are describing is something akin to 'private inheritance' from C++, and is not available in C#.
You cant do it directly, but you could override the properties in the child class and make them readonly e.g.
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class a
{
public virtual int item1 {get; set;}
public virtual int item2 { get; set; }
}
class b : a
{
public override int item1
{
get { return base.item1; }
set { }
}
}
class c : a
{
}
You could use interfaces to hide the property. The child class would implemented an interface that didn't have the property then it wouldn't appear.
You would need two interfaces for when you want the property and when you don't, thus making it a horrible hack.
You can override it and then Add a [Browsable(false)] tag to prevent showing it in designer.
Simple:
public class a:TextBox
{
[Browsable(false)]
public override string Text
{
get { return ""; }
set { }
}
}
Changing the accessibility of a virtual member is an inheriting class is specifically prohibited by the C# language spec:
The override declaration and the overridden base method have the same
declared accessibility. In other words, an override declaration cannot
change the accessibility of the virtual method. However, if the
overridden base method is protected internal and it is declared in a
different assembly than the assembly containing the override method
then the override method’s declared accessibility must be protected.
From section 10.6.4 Override methods
The same rules which apply to overriding method also apply to properties, so going from public to private by inheriting from the base class can't be done in C#.
What you actually need are interfaces:
public interface ProvidesItem1
{
int item1 { get; set; }
}
public interface ProvidesItem2
{
int item2 { get; set; }
}
class a : ProvidesItem1, ProvidesItem2
{
public int item1 { get; set; }
public int item2 { get; set; }
}
class b : ProvidesItem1
{
public int item1 { get; set; }
}
Then just pass the interfaces around. If the classes should use a common implementation, put that in a third class and let them derive from that class aswell as implement their respective interface.
Yes, it is possible. What say you on the delegation. I will try to give an idea of what is called "delegation" in OOP with a piece of code:
public class ClassA
{
// public
public virtual int MyProperty { get; set; }
// protected
protected virtual int MyProperty2 { get; set; }
}
public class ClassB
{
protected ClassC MyClassC;
public ClassB()
{
MyClassC = new ClassC();
}
protected int MyProperty2
{
get { return MyClassC.MyProperty2; }
set { MyClassC.MyProperty2 = value; }
}
protected int MyProperty
{
get { return MyClassC.MyProperty; }
set { MyClassC.MyProperty = value; }
}
protected class ClassC : ClassA
{
public new int MyProperty2
{
get { return base.MyProperty2; }
set { base.MyProperty2 = value; }
}
public override int MyProperty
{
get { return base.MyProperty; }
set { base.MyProperty = value; }
}
}
}
namespace PropertyTest
{
class a
{
int nVal;
public virtual int PropVal
{
get
{
return nVal;
}
set
{
nVal = value;
}
}
}
class b : a
{
public new int PropVal
{
get
{
return base.PropVal;
}
}
}
class Program
{
static void Main(string[] args)
{
a objA = new a();
objA.PropVal = 1;
Console.WriteLine(objA.PropVal);
b objB = new b();
objB.PropVal = 10; // ERROR! Can't set PropVal using B class obj.
Console.Read();
}
}
}
You can user new modifer.
Sample;
public class Duck
{
public string Color{get; set;}
public void Swim() { }
}
public class DonaldDuck : Duck
{
new public void Swim()
{
/*you could call in DonaldDuck.Swim only here but not public for DonaldDuck client.*/
}
}
If you wanna hide a member from base class then you will need to add a new base class let's call it baseA and your code should be as follows:
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class baseA
{
public int item2 { get; set; }
}
class a:baseA
{
public int item1 { get; set; }
}
class b : baseA { }
class c : a { }
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#
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.
Say I have code out there like this:
public class Base // I cannot change this class
{
public string Something { get; private set; }
public string Otherthing { get; set; }
public static Base StaticPreSet
{
get { return new Base { Something = "Some", Otherthing = "Other"}; }
}
public static Base StaticPreSet2
{
get { return new Base { Something = "Some 2", Otherthing = "Other 2"}; }
}
}
public class SubClass : Base // I can change this class all I want.
{
public string MoreData { get; set; }
// How can I wrap the PreSets here so that they return SubClass objects?
// Something like this:
public static SubClass MyWrappedPreset
{
get
{
// Code here to call the base preset and then use it as the
// base of my SubClass instance.
}
}
}
What makes this complicated is the Something property. It has a private setter. So I can't set it in the subclass. The only way it can be set is is via the preset properties.
Is there a way to wrap the StaticPreSet property in my SubClass so that it will return an object of type SubClass?
// I cannot change this base class.
Given that you can't change the base class, there is no way to cause it to change behavior (ie: return a different class at runtime).
If you could influence the design of the base class static methods, you could redesign it in a way to be flexible enough to provide this functionality. However, without changing it, this won't work.
Edit in response to edit:
You could create a new static method that does what you are showing, like so:
public static SubClass MyWrappedPreset
{
get
{
// Code here to call the base preset and then use it as the
// base of my SubClass instance.
Base baseInstance = Base.StaticPreSet;
SubClass sc = new SubClass(baseInstance); // Create a new instance from your base class
return sc;
}
}
However, this provides a completely new, unrelated property - you'd have to access it via SubClass.MyWrappedPreset, not the Base class.
Static fields in a class "have nothing to do with it".
Basically, except access to private static fields, id doesn't matter in which class you put them - they behave the same.
If you inherit a class, and you declare another static field with the same name of a static field on the base class, you will simply 'hide' it. Example for you:
using System;
public class Base // I cannot change this class
{
public string Something { get; set; }
public string Otherthing { get; set; }
public static Base StaticPreSet
{
get { return new Base { Something = "Some", Otherthing = "Other"}; }
}
public static Base StaticPreSet2
{
get { return new Base { Something = "Some 2", Otherthing = "Other 2"}; }
}
}
public class SubClass : Base // I can change this class all I want.
{
public string MoreData { get; set; }
public static SubClass StaticPreSet2
{
get { return new SubClass { Something = "inherited", Otherthing=""}; }
}
}
public class Test
{
public static void Main()
{
Console.WriteLine(SubClass.StaticPreSet2.Something);
}
}
Will write "inherited".