It Shadows. What?

Published 10 March 04 04:04 AM | despos

OK with this post I publicly admit that perhaps I'm not that strong with subtle and fine features of OOP. Let's take the Shadows keyword in VB.NET (or the new modifier in C#).

Can anybody provide a real-world example of their usefulness?

I went through some of the MSDN examples full of hope. Disregarded. You know those brilliant examples where you have class A; then class B that derives from A; C from B; D from C. Etc etc.

Any help?

A poor soul in a dark shadow

Comments

# Michael Teper said on March 9, 2004 11:04 PM:

This is from memory:

public class Base
{
public void MethodOne()
{
// ...
}

// other declarations
}

public class Derived : Base
{
private new void MethodOne()
{
return;
}
}

I've just hid MethodOne in the derived class.

# Kathleen Dollard said on March 9, 2004 11:15 PM:

Dino,

Actually, Shadows and CSharp’s new are not equivalent

VB.NET’s Shadows goes to the lack of a new slot modifier
.method public instance void SubA() cil managed

While VB.NET’s Overloads goes to the hidebysig IL construct
.method public hidebysig instance void SubB() cil managed

C#’s new goes to the hidebysig IL construct
.method public hidebysig instance void SubA() cil managed

Note that Shadows is the same as declaring a method with no modifiers. The VB compiler normally wouldn’t allow this. It creates a new name, effectively blocking all of the overloads with that name in the inheritance hierarchy. I am not aware of a C# equivalent.

VB.NET default
.method public instance void SubB() cil managed

C# default
.method public hidebysig instance void SubA() cil managed

The IL hidebysig, in either C# or VB.NET blocks methods in derived classes only for that overload. Other overloads are unaffected. Note that this is the default behavior in C# and requires the Overload keyword in C# clarifying what’s going on. C# would also prefer you clarify your intent by using the keyword new when you’re replacing the base class method, although it isn’t required.

Whew, OK, we cleared that up right? ;)

Your question was when they are useful. Try this exercise. If you have ClassB derived from ClassA, with a SubA and SubB in ClassA that are Overloaded (new) and overridden respectively in ClassB. Give all methods some marker action such as “Console.WriteLine(ClassName & MethodName)”

Dim B As New ClassB
Dim A As ClassA = B

A.SubA
B.SubA
A.SubB
B.SubB

The Overloaded/new SubA will give different results, while the overridden SubB give identical results.

Why do you care? If you design a system dependent on this behavior, you are a very sick person and I do not want to invite you to any tea parties. But we are in a new world. You don’t necessarily control your base classes. Let’s say you override the TextBox class and add a “Foo” method. All’s well, until Microsoft adds a Foo method that is not overridable. Without the HideBySig modifier, you’d be toast. You would have to change your class, and all derived classes, which, btw, you released to the wild and has been used by 379 programmers you’ve never met. HideBySig rides to the rescue and allows you to block the TextBox Foo method with your tried and true one. Still not a dandy scenario because you’re derived classes can’t use the TextBox Foo method, but you can always add an MSFoo method that wraps it if you need to.

Without HideBySig the .NET framework (and your classes) could not evolve because EVERY addition of a new method or overload would be a breaking change. That would be bad. So love HideBySig, Overloads, and new, but use them with some common sense, and you are not a lesser programmer if you never touch the stuff.

I have yet to understand a good reason for the HideByName behavior or Shadows. I think it’s a rather nasty construct because you may only have one overload when you use it (in which case behavior matches Overloads). But later programmers will have to figure out why new overloads are also hidden. The closest thing to an explanation I have managed is in the Foo scenario you have a Foo and MS has a Foo and you don’t want the two functionalities confused - you don’t want one overload of Foo to call MS’s Foo, and the other to call your Foo because you think that would be confusing. In this case, you can block all current and future MS Foo’s with one keyword. Radical.

Kathleen

# dhananjay said on March 9, 2004 11:49 PM:

Actually "new" keyword here is for making coad more readable and maintenanble.
It does not have any programatic significance.

# Frans Bouma said on March 10, 2004 03:45 AM:

(Somewhat general example, but you get the drill)
Consider an entity class OrderEntity and it has a typed property Employee which returns an EmployeeEntity object.

You've created new classes ManagerEntity and ClerkEntity which derive from Employee and you want to create ManagerOrder and ClerkOrder. These have to have typed Employee properties as well, so ClerkOrder should return a ClerkEntity from Employee, not just an EmployeeEntity.

You can't override 'Employee' and give it a new return type. You have to 'shadow' / hide it away with the new/shadow statement to avoid compiler errors.

# Seb said on March 10, 2004 04:14 AM:

Hi Dino,

FOA, thanks for everything you're bringing to us developers ; I'm glad to learn that you'll probably be speaking at our local swiss UG sometime in april !

Back on "Shadows", to add a concrete experience to Kathleen's comment : I work for a customer that purchased an asp.net-based framework. That framework defines a subclass of HttpApplication, let's call it TheirApplication. Any app based on this framework has its Global class inherit from TheirApplication rather than HttpApplication.

An annoying thing is that TheirApplication implements the Session_Start sub without the overridable keyword ... So without Shadows, we would not be able to add any session-startup code in the Global class.

This is a real-world example that shows :
- the "good" approach would probably be to request a change to our supplier and ask him to add the overridable keyword to Session_Start
- "Shadows" is dirtier from a pure OO standpoint, but gives us a viable temporary solution.

Another example : subclassing SoapHttpClientProtocol and redefining the Invoke method. In other words, shadows is one of the hacker's best friends :)

Personally I wish .NET methods were virtual by default, like in Java

-S

# Adrian Florea said on March 10, 2004 06:10 AM:

http://www.artima.com/intv/nonvirtualP.html

# Ian Griffiths said on March 10, 2004 07:50 AM:

The reason this exists is a side effect of being able to derive from a base class that may be defined in a different component without suffering breakage when the base class is modified.

If you declare a function in a derived class that does *not* shadow an existing member, the compiler will add the flags it would have added for the 'new' keyword. This means that if the base class later evolves to get a member of the same name, you are not hosed. (Unlike in Java, where you are in serious trouble if this happens.) The CLR is designed to be able to allow base and derived classes to have distinct members that happen to have exactly the same signature for this sole reason.

So why is it surfaced in the languages? This is so that you have an emergency quick fix if you need to recompile your code and discover that the author of the base class has recently added a method that has the same name and signature as a method you added some time ago to your derived class. The Right Thing to do here would be to rename your method (or convince the base class author to rename their method). But sometimes you just don't have time to do that. As a quick fix, the 'new' keyword lets you say "Yes, I know this collides with a method in the base class, so please act like the method in the base class wasn't even there."

It's a code smell - a sign that something is wrong. (In this case, two distinct but identically-named methods.) If you ever use new at all, you should aim to remove it at the earliest opportunity. It's not something you would ever choose to design in.

# Jonathan Crossland said on March 10, 2004 10:01 AM:


I required the new keywoard on the System.Web.UI.TemplateControl.LoadControl

this is purely because it is not overridable.

I would also say that it is useful to *hack* at something

# Marc said on March 24, 2004 08:22 AM:

Well, we've just run across a case where we were very glad for the "new" keyword in C#. Imagine this: we have a base grid class, from which we'd like to derive our own custom grid (with some added functionality), plus a read-only variant thereof.

Now, unforutnately, the base grid class exposes way too many properties and methods for our read-only grid, so using the "new" keyword, we can "hide" those unwanted properties, and make it "safe" to use the read-only grid.

E.g. we can completely "blank out" an unwanted property by re-introducing a new property with the same name, making that [Browsable(false)] so it won't show up in the property inspector, and making it read-only by not providing a setXXX method for the property.

Coming from Delphi, I was used to base classes TCustomSomething to provide all properties and methods in a "protected" state, so that I could easily inherit a "MySomething" class and just expose all properties as public, or a "MyReadonlySomething", which would expose only some of the properties (that made sense to the readonly case). This doesn't seem to be something most C# component developers do for now, unfortunately...... so I'm glad I can use the "new" keyword for "hiding out" some properties and methods.

Real world enough?? ;-)
Marc

# Jeffrey Palermo said on March 25, 2004 02:53 AM:

On your blog: "Can anybody provide a real-world example of their usefulness? " regarding the C# new keyword, I have used it out of necessity. I have a class that inherits from System.Web.UI.Page in my ASP.NET application. I call it MyNamspace.Page. This page has a couple of properties necessary for every page in my app. I also have a UIPage class that inherits from my Page class. This page is further specialized and includes more processing for the main UI pages of the app. On my Page class, I have a property used everywhere in the app called User. It is of my own custom type. Well, System.Web.UI.Page already has a User property that I don't care about, so I declare in my Page class:
public new MyUserType User{
get{}set{}
}

Also I have custom UserControl base classes, and to get to my custom Page from the usercontrol, I could cast the
existing Page property to my custom page every time, but instead, I (in my base UserControl class) declare:
public new MyNamspace.Page Page
{
get{ return (MyNamespace.Page)base.Page;}
}
so that my custom page class is used instead.

The new keyword is not that glamorous, but without it, my job would have been just a little more difficult.

# amit sengupta said on April 8, 2004 01:07 AM:

imports System.io
'CLASS classA
public class classA

public sub showStatus()

System.console.writeline("inside the class A")

end sub

'CLASS classB
public class classB
public shadows showStaus() 'SHADOWS
System.console.writeline("inside the class B")
end sub

Module module1
sub Main()
dim objA as classA=new classB()
objA.showStatus()
end sub
end module
'RESULT AT CONSOLE
inside the classA

# amit sengupta said on April 8, 2004 01:13 AM:

imports System.io
'CLASS classA
public class classA

public sub showStatus()

System.console.writeline("inside the class A")

end sub

'CLASS classB
public class classB:inherits classA
public shadows showStaus() 'SHADOWS
System.console.writeline("inside the class B")
end sub

Module module1
sub Main()
dim objA as classA=new classB()
objA.showStatus()
end sub
end module
'RESULT AT CONSOLE
inside the classA

# Brent said on November 28, 2007 10:49 PM:

I'm currently using shadows for the following case.

BaseClassA implements InterfaceA

DerivedClassB inherits BaseClassA

BaseClassA has Property1 that is read/write

In DerivedClassB, I also use Property1, but it should be ReadOnly, so I Shadow it to change the property accessor.

# mean boss said on April 13, 2008 04:07 AM:

How do you cope with difficult people at work?

# ikitClaw said on May 8, 2008 09:30 AM:

Seems like a tired topic, but I've got a real use for Shadow - when using XML serialization on classes to match data structures (for instance, ebXML business signals), many data items are named differently but in fact contain common data. Creating a wrapper class for individual but very similar classes allows not-very-dissimilar objects to be treated the same where they rightly should, but in the class declarations, serialization tags for class members are an extra layer above basic naming/overloading and thus provide a scenario where Shadow is actually useful.

Don't believe me ? Take a peek ;)

_____________________________________________

   Public Class SignalWrapper

       Public thisMessageIdentifier As thisMessageIdentifier

       Public thisMessageDateTime As thisMessageDateTime

       Public receivedDocumentDateTime As receivedDocumentDateTime

       Public receivedDocumentIdentifier As receivedDocumentIdentifier

   End Class

   Public Class ReceiptAcknowledgement

       Inherits SignalWrapper

   End Class

   Public Class ReceiptAcknowledgementException

       Inherits SignalWrapper

       <XmlElement("theMessageDateTime")> Public Shadows thisMessageDateTime As thisMessageDateTime

       <XmlElement("theOffendingDocumentDateTime")> Public Shadows receivedDocumentDateTime As receivedDocumentDateTime

       <XmlElement("theOffendingDocumentIdentifier")> Public Shadows receivedDocumentIdentifier As receivedDocumentIdentifier

   End Class

__________________________________________

The ~Exception class is effectively identical to the normal class, both derive from SignalWrapper, but the repeat declarations of methods that need Shadow'ing is required in order to specify different XML element names for serialization.

# Suddenly slim diet said on May 14, 2008 07:29 PM:

Hi - just wanted to say good design and blog - cu Frank

# Tito Jermaine said on June 3, 2008 06:49 PM:

Something that I don't know that got pointed out (maybe I missed it in the see of comments), but shadowing has a really annoying side-effect that if you're writing OOP code and using base class references, you're not going to get what you expect.  In my experience, the type member that will be used is determined by the type of the reference, not the type of the underlying object when shadowing is in play.  For example:

public class A

{

   public virtual void Test()

   {

       System.Diagnostics.Debug.WriteLine("Test in A");

   }

   public void TestShadow()

   {

       System.Diagnostics.Debug.WriteLine("TestShadow in A");

   }

}

public class B : A

{

   public override void Test()

   {

       System.Diagnostics.Debug.WriteLine("Test in B");

   }

   public new void TestShadow()

   {

       System.Diagnostics.Debug.WriteLine("TestShadow in B");

   }

}

class Program

{

   static void Main(string[] args)

   {

       A a = new A();

       B b = new B();

       A c = new B();

       a.Test();

       a.TestShadow();

       b.Test();

       b.TestShadow();

       c.Test();

       c.TestShadow();

   }

}

Results in this:

Test in A

TestShadow in A

Test in B

TestShadow in B

Test in B

TestShadow in A (This is where shadowing breaks OOP)

# Ab workout machine said on June 24, 2008 04:57 AM:

Thanks for the post. I couldnt agree with you more.

Leave a Comment

(required) 
(required) 
(optional)
(required)