Understanding inherited and base items in a list - c#

This is a question that might perhaps be foolish, but I can't seem to reason my way around it so I have come here for some thoughts. It's about inheritance and lists.
Alright, so I have two classes: TestClass and DerivedTestClass. DerivedTestClass is derived from TestClass. Both classes have a method called 'Method1'.
These are both very simple methods. They just have a message box saying what method is being accessed. In fact, let me write the code just to remove ambiguity:
public void Method1(String typeName)
{
MessageBox.Show("Base method 1 + Type: "+typeName);
}
This is for the base class (TestClass).
public void Method1(String typeName)
{
MessageBox.Show("Derived method 1 + Type: "+typeName);
}
This is for the derived class (DerivedTestClass).
Next I created an instance of both of these and called the Method1 for each. And it's exactly as you'd expect. When I called it for the base class I for the first message box, and when I called the derived class I got the second one.
No mysteries so far, but now we get to the part where my understanding seems to be lacking.
I create a List into which I add both instances I have created: the instance of the base class and the instance of the derived class. Then I created a foreach loop which went through each item in the list and called Method1, as follows:
foreach (var tc in listT)
{
tc.Method1(tc.GetType().Name);
}
In both cases the base method is called. Now in one respect I get that as the list itself is the type of the base class. The problem is if I look at the types. If I ask the first item in the list what its type is, it will say TestClass. If I ask the second item in the list what its type is, it will say DerivedBaseClass.
Now one can solve this by casting each item within the list to its own type. But it can require a long list of if statements based on how many derived types you have. Also, and I suppose this is the heart of the problem, I'm just confused about ever having to cast something to that which it already is. If the item is a DerivedBaseClass (as evidenced by the GetType()), it seems odd that I have to cast that to DerivedBaseClass. Can I rely on GetType in these situations? Should it come with an asterisk that says 'well the memory declared is only enough for the base class, and while this is a derived class, it's currently in the form of a base class'?
So you could say I'm a bit confused and looking for clarification.

Two things:
You aren't overriding Method1, you are hiding it in the derived class so you can consider these methods as completely different things entirely.
Your list only contains references to the base type, and as such will only call the methods it exposes.
To fix this, change your types to something like this, note the virtual base method and the override in the derived class:
public class BaseType
{
public virtual void Method1(String typeName)
//^^^^^^^ This
{
MessageBox.Show("Base method 1 + Type: "+typeName);
}
}
public class DerivedType : BaseType
{
public override void Method1(String typeName)
//^^^^^^^^ And this
{
MessageBox.Show("Derived method 1 + Type: "+typeName);
}
}

Related

Call static method from generic abstract class without specifying a type

I have an abstract class like this:
public abstract class BaseCamera<TCamera> : ICamera where TCamera : ManagedCameraBase
{
public static uint GetNumberOfCameras()
{
using (var bus = new ManagedBusManager())
{
bus.RescanBus();
return bus.GetNumOfCameras();
}
}
}
And want to call it like this:
BaseCamera.GetNumberOfCameras()
It makes sense to me, because since this is an abstract class, only the concrete children classes must choose a TCamera, and the base class wants to get the number of all cameras, no matter they type.
However, the compiler does not approve:
Using the Generic type 'BaseCamera' requires 1 type
arguments.
Is there some way around it or do I need to create a new class just for this?
I think it is worth pointing out that ManagedCameraBase is a class from an external API I'm wrapping. Therefore, I do not want to include it in any of my calls for BaseCamera and that is why I'm trying to avoid specifying a type.
because since this is an abstract class, only the concrete children classes must choose a TCamera
That's not how generics work. This has nothing at all to do with the class being abstract. If the class was generic and not abstract you would still need to specify a generic argument in order to call a static method of the class. On top of that, there's nothing to say that a child class can't also be generic. Yours may happen to not be, but there's nothing requiring that to be the case.
Now, in your particular case, the GetNumberOfCameras method doesn't use the generic argument (T) at all, so it doesn't matter what generic argument you provide, you can put in whatever you want and it'll work just fine. Of course, because of that, it's a sign that this method probably doesn't belong in this class; it should probably be in another class that this class also uses.
Here's the problem. The static method GetNumberOfCameras belongs to the class that contains it, but a generic class actually gets compiled into separate classes for each type. So, for example if you had this:
public class Foo<T>
{
static int foo = 0;
public static void IncrementFoo()
{
foo++;
}
public static int GetFoo()
{
return foo;
}
}
And then you did this:
Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());
You will see that the first call to GetFoo will return one, but the second will return zero. Foo<string>.GetFoo() and Foo<int>.GetFoo() are two separate static method that belong to two different classes (and access two different fields). So that's why you need a type. Otherwise the compiler won't know which static method of which class to call.
What you need is a non-generic base class for your generic class to inherit from. So if you do this:
public class Foo<T> : Foo
{
}
public class Foo
{
static int foo = 0;
public static void IncrementFoo()
{
foo++;
}
public static int GetFoo()
{
return foo;
}
}
Then this:
Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());
Will give you what you might have expected at first. In other words, both calls to GetFoo will return the same result. And, of course, you don't actually need the type argument anymore and can just do:
Foo.IncrementFoo();
Or course, the alternative is to just move your static methods into an entirely different class if there's no reason why it should be part of BaseCamera
Well, there are a couple of things here you need to understand better.
First of all, I see a problem with your design. The method you are attempting to stick into this class really has nothing to do with the generic nature of it. In fact, you are instantiating another class to do the job so it really does not belong here at all.
If it actually had something to do with an object that inherits from ManagedCameraBase, the method would probably not need to be static but rather an instance method. You can then decide on the accessor (public/private) based on usage.
Finally, you need to understand what Generics actually do under the covers. When you use the generic base with a particular type, an underlying specialized type is created for you behind the scenes by the compiler. If you were to use the static method, the compiler would need to know the type you are targeting in order to create the static instance that will serve your call. Because of this, if you call the static method, you must pass a type and you will end up with as many static instances as the types you use to call it (the types must derive from ManagedCameraBase, of course).
As you can see, you should either move that method out to some helper class or something of the sort, or make it a non-static, instance method.

Polymorphism with generics - strange behavior

Pluggable framework
Imagine a simple pluggable system, which is pretty straightforward using inheritance polymorphism:
We have a graphics rendering system
There are different types of graphics shapes (monochrome, color, etc.) that need rendering
Rendering is done by a data-specific plugin, e.g. a ColorRenderer will render a ColorShape.
Every plugin implements IRenderer, so they can all be stored in an IRenderer[].
On startup, IRenderer[] is populated with a series of specific renderers
When data for a new shape is received, a plugin is chosen from the array based on the type of the shape.
The plugin is then invoked by calling its Render method, passing the shape as its base type.
The Render method is overridden in each descendant class; it casts the Shape back to its descendant type and then renders it.
Hopefully the above is clear-- I think it is a pretty common sort of setup. Very easy with inheritance polymorphism and run-time casting.
Doing it without casting
Now the tricky part. In response to this question, I wanted to come up with a way to do this all without any casting whatsoever. This is tricky because of that IRenderer[] array-- to get a plugin out of the array, you would normally need to cast it to a specific type in order to use its type-specific methods, and we can't do that. Now, we could get around that by interacting with a plugin only with its base class members, but part of the requirements was that the renderer must run a type-specific method that has a type-specific data packet as an argument, and the base class would not be able to do that because there is no way to pass it a type-specific data packet without a casting it to the base and then back to the ancestor. Tricky.
At first I thought it was impossible, but after a few tries I found I could make it happen by juking the c# generic system. I create an interface that is contravariant with respect to both plugin and shape type and then used that. Resolution of the renderer is decided by the type-specific Shape. Xyzzy, the contravariant interface makes the cast unnecessary.
Here is the shortest version of the code I could come up with as an example. This compiles and runs and behaves correctly:
public enum ColorDepthEnum { Color = 1, Monochrome = 2 }
public interface IRenderBinding<in TRenderer, in TData> where TRenderer : Renderer
where TData: Shape
{
void Render(TData data);
}
abstract public class Shape
{
abstract public ColorDepthEnum ColorDepth { get; }
abstract public void Apply(DisplayController controller);
}
public class ColorShape : Shape
{
public string TypeSpecificString = "[ColorShape]"; //Non-virtual, just to prove a point
override public ColorDepthEnum ColorDepth { get { return ColorDepthEnum.Color; } }
public override void Apply(DisplayController controller)
{
IRenderBinding<ColorRenderer, ColorShape> renderer = controller.ResolveRenderer<ColorRenderer, ColorShape>(this.ColorDepth);
renderer.Render(this);
}
}
public class MonochromeShape : Shape
{
public string TypeSpecificString = "[MonochromeShape]"; //Non-virtual, just to prove a point
override public ColorDepthEnum ColorDepth { get { return ColorDepthEnum.Monochrome; } }
public override void Apply(DisplayController controller)
{
IRenderBinding<MonochromeRenderer, MonochromeShape> component = controller.ResolveRenderer<MonochromeRenderer, MonochromeShape>(this.ColorDepth);
component.Render(this);
}
}
abstract public class Renderer : IRenderBinding<Renderer, Shape>
{
public void Render(Shape data)
{
Console.WriteLine("Renderer::Render(Shape) called.");
}
}
public class ColorRenderer : Renderer, IRenderBinding<ColorRenderer, ColorShape>
{
public void Render(ColorShape data)
{
Console.WriteLine("ColorRenderer is now rendering a " + data.TypeSpecificString);
}
}
public class MonochromeRenderer : Renderer, IRenderBinding<MonochromeRenderer, MonochromeShape>
{
public void Render(MonochromeShape data)
{
Console.WriteLine("MonochromeRenderer is now rendering a " + data.TypeSpecificString);
}
}
public class DisplayController
{
private Renderer[] _renderers = new Renderer[10];
public DisplayController()
{
_renderers[(int)ColorDepthEnum.Color] = new ColorRenderer();
_renderers[(int)ColorDepthEnum.Monochrome] = new MonochromeRenderer();
//Add more renderer plugins here as needed
}
public IRenderBinding<T1,T2> ResolveRenderer<T1,T2>(ColorDepthEnum colorDepth) where T1 : Renderer where T2: Shape
{
IRenderBinding<T1, T2> result = _renderers[(int)colorDepth];
return result;
}
public void OnDataReceived<T>(T data) where T : Shape
{
data.Apply(this);
}
}
static public class Tests
{
static public void Test1()
{
var _displayController = new DisplayController();
var data1 = new ColorShape();
_displayController.OnDataReceived<ColorShape>(data1);
var data2 = new MonochromeShape();
_displayController.OnDataReceived<MonochromeShape>(data2);
}
}
If you run Tests.Test1() the output will be:
ColorRenderer is now rendering a [ColorShape]
MonochromeRenderer is now rendering a [MonochromeShape]
Beautiful, it works, right? Then I got to wondering... what if ResolveRenderer returned the wrong type?
Type safe?
According to this MSDN article,
Contravariance, on the other hand, seems counterintuitive....This seems backward, but it is type-safe code that compiles and runs. The code is type-safe because T specifies a parameter type.
I am thinking, there is no way this is actually type safe.
Introducing a bug that returns the wrong type
So I introduced a bug into the controller so that is mistakenly stores a ColorRenderer where the MonochromeRenderer belongs, like this:
public DisplayController()
{
_renderers[(int)ColorDepthEnum.Color] = new ColorRenderer();
_renderers[(int)ColorDepthEnum.Monochrome] = new ColorRenderer(); //Oops!!!
}
I thought for sure I'd get some sort of type mismatch exception. But no, the program completes, with this mysterious output:
ColorRenderer is now rendering a [ColorShape]
Renderer::Render(Shape) called.
What the...?
My questions:
First,
Why did MonochromeShape::Apply call Renderer::Render(Shape)? It is attempting to call Render(MonochromeShape), which obviously has a different method signature.
The code within the MonochromeShape::Apply method only has a reference to an interface, specifically IRelated<MonochromeRenderer,MonochromeShape>, which only exposes Render(MonochromeShape).
Although Render(Shape) looks similar, it is a different method with a different entry point, and isn't even in the interface being used.
Second,
Since none of the Render methods are virtual (each descendant type introduces a new, non-virtual, non-overridden method with a different, type-specific argument), I would have thought that the entry point was bound at compile time. Are method prototypes within a method group actually chosen at run-time? How could this possibly work without a VMT entry for dispatch? Does it use some sort of reflection?
Third,
Is c# contravariance definitely not type safe? Instead of an invalid cast exception (which at least tells me there is a problem), I get an unexpected behavior. Is there any way to detect problems like this at compile time, or at least to get them to throw an exception instead of doing something unexpected?
OK, first of all, do not write generic types like this. As you have discovered, it rapidly becomes a huge mess. Never do this:
class Animal {}
class Turtle : Animal {}
class BunchOfAnimals : IEnumerable<Animal> {}
class BunchOfTurtles : BunchOfAnimals, IEnumerable<Turtle> {}
OH THE PAIN. Now we have two paths by which to get an IEnumerable<Animal> from a BunchOfTurtles: Either ask the base class for its implementation, or ask the derived class for its implementation of the IEnumerable<Turtle> and then covariantly convert it to IEnumerable<Animal>. The consequences are: you can ask a bunch of turtles for a sequence of animals, and giraffes can come out. That's not a contradiction; all the capabilities of the base class are present in the derived class, and that includes generating a sequence of giraffes when asked.
Let me re-emphasize this point so that it is very clear. This pattern can create in some cases implementation-defined situations where it becomes impossible to determine statically what method will actually be called. In some odd corner cases, you can actually have the order in which the methods appear in the source code be the deciding factor at runtime. Just don't go there.
For more on this fascinating topic I encourage you to read all the comments to my 2007 blog post on the subject: https://blogs.msdn.microsoft.com/ericlippert/2007/11/09/covariance-and-contravariance-in-c-part-ten-dealing-with-ambiguity/
Now, in your specific case everything is nicely well defined, it's just not defined as you think it ought to be.
To start with: why is this typesafe?
IRenderBinding<MonochromeRenderer, MonochromeShape> component = new ColorRenderer();
Because you said it should be. Work it out from the point of view of the compiler.
A ColorRenderer is a Renderer
A Renderer is a IRenderBinding<Renderer, Shape>
IRenderBinding is contravariant in both its parameters, so it may always be made to have a more specific type argument.
Therefore a Renderer is an IRenderBinding<MonochromeRenderer, MonochromeShape>
Therefore the conversion is valid.
Done.
So why is Renderer::Render(Shape) called here?
component.Render(this);
You ask:
Since none of the Render methods are virtual (each descendant type introduces a new, non-virtual, non-overridden method with a different, type-specific argument), I would have thought that the entry point was bound at compile time. Are method prototypes within a method group actually chosen at run-time? How could this possibly work without a VMT entry for dispatch? Does it use some sort of reflection?
Let's go through it.
component is of compile-time type IRenderBinding<MonochromeRenderer, MonochromeShape>.
this is of compile-time type MonochromeShape.
So we are calling whatever method implements IRenderBinding<MonochromeRenderer, MonochromeShape>.Render(MonochromeShape) on a ColorRenderer.
The runtime must figure out which interface is actually meant. ColorRenderer implements IRenderBinding<ColorRenderer, ColorShape> directly and IRenderBinding<Renderer, Shape> via its base class. The former is not compatible with IRenderBinding<MonochromeRenderer, MonochromeShape>, but the latter is.
So the runtime deduces that you meant the latter, and executes the call as though it were IRenderBinding<Renderer, Shape>.Render(Shape).
So which method does that call? Your class implements IRenderBinding<Renderer, Shape>.Render(Shape) on the base class so that's the one that's called.
Remember, interfaces define "slots", one per method. When the object is created, each interface slot is filled with a method. The slot for IRenderBinding<Renderer, Shape>.Render(Shape) is filled with the base class version, and the slot for IRenderBinding<ColorRenderer, ColorShape>.Render(ColorShape) is filled with the derived class version. You chose the slot from the former, so you get the contents of that slot.
Is c# contravariance definitely not type safe?
I promise you it is type safe. As you should have noticed: every conversion you made without a cast was legal, and every method you called was called with something of a type that it expected. You never invoked a method of ColorShape with a this referring to a MonochromeShape, for instance.
Instead of an invalid cast exception (which at least tells me there is a problem), I get an unexpected behavior.
No, you get entirely expected behaviour. You just have created a type lattice that is extraordinarily confusing, and you don't have a sufficient level of understanding of the type system to understand the code you wrote. Don't do that.
Is there any way to detect problems like this at compile time, or at least to get them to throw an exception instead of doing something unexpected?
Don't write code like that in the first place. Never implement two versions of the same interface such that they may unify via covariant or contravariant conversions. It is nothing but pain and confusion. And similarly, never implement an interface with methods that unify under generic substitution. (For example, interface IFoo<T> { void M(int); void M(T); } class Foo : IFoo<int> { uh oh } )
I considered adding a warning to that effect, but it was difficult to see how to turn off the warning in the rare cases where it is desirable. Warnings that can only be turned off with pragmas are poor warnings.
First. MonochromeShape::Apply call Renderer::Render(Shape) because of the following:
IRenderBinding<ColorRenderer, ColorShape> x1 = new ColorRenderer();
IRenderBinding<Renderer, Shape> x2 = new ColorRenderer();
// fails - cannot convert IRenderBinding<ColorRenderer, ColorShape> to IRenderBinding<MonochromeRenderer, MonochromeShape>
IRenderBinding<MonochromeRenderer, MonochromeShape> c1 = x1;
// works, because you can convert IRenderBinding<Renderer, Shape> toIRenderBinding<MonochromeRenderer, MonochromeShape>
IRenderBinding<MonochromeRenderer, MonochromeShape> c2 = x2;
So in short: ColorRenderer inherits from Renderer and that in turn implements IRenderBinding<Renderer, Shape>. This interface is what allows ColorRendered to be implicitly converted to IRenderBinding<MonochromeRenderer, MonochromeShape>. This interface is implemented by class Renderer and so it's not suprising that Renderer.Render is called when you call MonochromeShape::Apply. The fact you pass instance of MonochromeShape and not Shape is not a problem exactly because TData is contravariant.
About your second question. Dispatch by interface is virtual just by definition. In fact, if method implements some method from interface - it's marked as virtual in IL. Consider this:
class Test : ITest {
public void DoStuff() {
}
}
public class Test2 {
public void DoStuff() {
}
}
interface ITest {
void DoStuff();
}
Method Test.DoStuff has following signature in IL (note virtual:
.method public final hidebysig virtual newslot instance void
DoStuff() cil managed
Method Test2.DoStuff is just:
.method public hidebysig instance void
DoStuff() cil managed
As for third question I think it's clear from above that it behaves as expected and is type-safe exactly because no invalid cast exceptions are possible.

Instancing an abstract class?

public abstract class T
{
public abstract IEnumerable<T> MakeOneMove();
public IEnumerable<T> MakeOneMove(string evt)
{
List<T> returnList = new List<T>();
IEnumerable<T> steps = MakeOneMove();
foreach (T step in steps)
{
if (step.Event == evt)
{
returnList.Add(step);
}
}
return returnList;
}
and elsewhere the class is used like this:
T currentImpl = pendingImpl.Pop();
IEnumerable<T> nextImpl = currentImpl.MakeOneMove();
foreach (ConfigurationBase next in nextImpl){
}
I am confused about two things. It seems like class T is being instanced , but class T is an abstract class. I thought this wasn't possible. I thought only non-abstract subclasses of the abstract class could be instanced. Also, in the class, makeonemove() is called, but isn't the version with no arguments not overridden and therefore not defined? it seems to me like this code shouldn't compile, yet it does.
I am confused about two things. It seems like class T is being
instanced , but class T is an abstract class. I thought this wasn't
possible. I thought only the subclass could be instanced.
abstract class T is not being instantiated, rather it is just a pointer to a concrete implementation of the abstract class.
Also, in the
class, makeonemove() is called, but isn't the version with no
arguments not overridden? it seems to me like this code shouldn't
compile, yet it does.
This is one of the benefits of using an Abstract Class. It allows you to provide a "base" implementation of its members that can be overridden in derived classes.
No, The class T is abstract. In the method call T currentImpl = pendingImpl.Pop(); the T there just means that the object returned will be a type which derives from T, it effectively establishes (Declares) the type of the variable named currentImpl, not the type of the object itself.
The actual type of the object being instantiated will be whatever type pendingImpl.Pop() creates. It looks like Pop() is what is called a factory method. You would have to look at how it is implemented to see exactly what type is instantiates and returns.
No, T just means that the class has to be convertible to T (ie it iherits from it and can be cast as T).
I suggest checking here to read up on inheritance:
http://www.csharp-station.com/Tutorial/CSharp/lesson08
And here to read about casting:
http://csharp-station.com/Tutorial/CSharp/Lesson22
Essentially if a class inherits another, it can be cast into an instance of the class and is thus treated as that class for the cast.
So say I made a Class H that inherited from T, then cast it to T, for the duration of that cast, H would essentially be disguised as T and you could only access the elements it inherits from T. So say I gave H a function called 'MakeTwoMoves', then made an instance of H called 'hi' (eg H hi = new H();) I could call MakeOneMove and MakeTwoMoves. Once it is cast to T however (eg (T)H) you MakeTwoMoves is no longer accessible because it's not declared in T, it's something unique to H.
What this means for your code however is that pendingImpl most likely would contain an array of instances of classes that have inherited from T (like the H in my example). They are then cast inside the pop method (or possibly earlier, ie before being put in the internal array) and come out as T, so each instance could be a completely different class but the only thing you know about them is that they inherit from T.
I hope that cleared things up a bit, T isn't the most intuitive name to work with.

c# generics on a method with the constraint that the type must be of "this" type

I have a C# class hierarchy with a common base type and two derived types. I want to declare an abstract method on the base class something like this :
public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass
... and I want this method to be implemented in the derived classes such that T is the type of that derived type, for each of the derived types, ie, in derived class A:
public override IEnumerable<A> GetSiblings<A>() { ... }
... and in derived class B ...
public override IEnumerable<B> GetSiblings<B>() { ... }
Put another way, each derived class must implement the method so that it returns an IEnumerable of items of the same type. Is there any way to implement this in C# ?
Well, you can hardly call a method generic if it only accepts a parameter of a single type, and your method signatures will have different return types which isn't allowed. Why don't you define an interface for all of these classes and simply return an IEnumerable<IMyClass>?
You can't do this because the return types are different. Simple as that. The reason is if you create an instance of A and stuff it into your base class(cast it) then the return type will be wrong.
You might be able to to use new instead but that might break your hierarchy.
This is not supported by the type system. It's a common enough problem, represented often as
class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired
But not a problem that has as yet been acted upon by the appropriate parties (be it the framework providers or C# team, not sure who).
Until it passes the critical "worth it" test as determined by costs (and opportunity costs) versus benefits, you'll have to work around it.
I found the solution. Apparently in C# 4.0, generic parameter types can be covariant, so what I've posted above will work. C# 3.5 or lower, and it doesn't work. Took a lot of Googling.

How to prevent inheritance for some methods?

How can I prevent inheritance of some methods or properties in derived classes?!
public class BaseClass : Collection
{
//Some operations...
//Should not let derived classes inherit 'Add' method.
}
public class DerivedClass : BaseClass
{
public void DoSomething(int Item)
{
this.Add(Item); // Error: No such method should exist...
}
}
The pattern you want is composition ("Has-a"), not inheritance ("Is-a"). BaseClass should contain a collection, not inherit from collection. BaseClass can then selectively choose what methods or properties to expose on its interface. Most of those may just be passthroughs that call the equivalent methods on the internal collection.
Marking things private in the child classes won't work, because anyone with a base type variable (Collection x = new DerivedClass()) will still be able to access the "hidden" members through the base type.
If "Is-a" vs "Has-a" doesn't click for you, think of it in terms of parents vs friends. You can't choose your parents and can't remove them from your DNA, but you can choose who you associate with.
You can't, in this instance inheritance is the wrong tool for the job. Your class needs to have the collection as a private member, then you can expose as much or as little of it as you wish.
Trying to hide a public member of a class in a derived class is generally a bad thing(*). Trying to hide it as a means of ensuring it won't be called is even worse, and generally won't work anyhow.
There isn't any standardized idiomatic means I know of to prevent a parent class' protected member from being accessed in a sub-derived type, but declaring a new public useless member of a clearly-useless kind would be one approach. The simplest such thing would be an empty class. For example, if class Foo declares an empty public class called MemberwiseClone, derivatives of Foo will be unable to call MemberwiseClone--probably a good thing if MemberwiseClone would break the invariants of class Foo.
(*) The only situation where it is appropriate is when a public method of a derived class returns a more specialized type than the corresponding method in the base class (e.g. a CarFactory.Produce() method may return a Car, while the FordExplorerFactory.Produce() method may return a FordExplorer (which derives from car). Someone who calls Produce() on what they think is a CarFactory (but happens to be a FordExplorerFactory) will get a Car (which happens to be a FordExplorer), but someone who calls Produce() on what is known at compile time to be a FordExplorerFactory will get a result that's known at compile time to be a FordExplorer.

Categories

Resources