override by name in c#?


G

Guest

Does c# support overriding by name and not signature
For instance I am building a custom collection class, that ca
only take a certain type of object
For this, I have added an override for add from the class view
and changed it fro
public int Add(object value
t
public int Add(MyItemClass value

This seems to work, but it generates a warning 'the new specifier is needed
because this method hides ...[that of the base class].
But even though I didn't think this would work to override the base clas
because it's not the same signature, it does, and apart from the warning, thi
is what I want to happen. But can a client still call the Add method from the bas
class, or is it totally overridden just by being called Add (i.e. doesn't need the sam
signature as the base class's method to override it)
 
Ad

Advertisements

B

Bob Powell [MVP]

If your collection class was derived from CollectionBase this wouldn't
happen because there is no Add method to override.

The reccommended way of creating your own stronlgy typed collection is to
derive from CollectionBase.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Image transition effects, automatic persistent configuration and
design time mouse operations all in April's issue of Well Formed
http://www.bobpowell.net/wellformed.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://royo.is-a-geek.com/siteFeeder/GetFeed.aspx?FeedId=41
 
J

Jon Skeet [C# MVP]

songie D said:
Does c# support overriding by name and not signature?
For instance I am building a custom collection class, that can
only take a certain type of object.
For this, I have added an override for add from the class view,
and changed it from
public int Add(object value)
to
public int Add(MyItemClass value)

That's not an override - it doesn't have the override modifier.
This seems to work, but it generates a warning 'the new specifier is needed,
because this method hides ...[that of the base class].'

That seems odd if you've changed the signature - it shouldn't.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
But even though I didn't think this would work to override the base class
because it's not the same signature, it does, and apart from the warning, this
is what I want to happen. But can a client still call the Add method from the base
class, or is it totally overridden just by being called Add (i.e. doesn't need the same
signature as the base class's method to override it)

It isn't overridden at all - it's hidden. Try calling it with:

BaseClass b = new DerivedClass();
b.Add(...);
 
M

Mark Broadbent

Try this songie, it works as you'd expect.

using System;

namespace Demo
{
/// <summary>
/// Summary description for Classes.
/// </summary>
public class Class1
{

public void Show(bool show)
{
if (show)
{
System.Windows.Forms.MessageBox.Show("Show from Class1");
}
}
}

public class Class2: Class1
{
public void Show(int show)
{
if (show>0)
{
System.Windows.Forms.MessageBox.Show("Show from Class2");
}
}
public static void Main()
{
Class1 c = new Class1();
c.Show(true); //show from class 1
Class2 d = new Class2();
d.Show(true); //show from class 1 (because member has been inherited)
d.Show(1); //show from class 2 (because member has different signature of
inherited member and creates overloaded member

}
}
}




--

Br,
Mark Broadbent
mcdba , mcse+i
=============
 
G

Guest

This gives the warning on getenumerator: (although foreach calls the correct version, i.e. the one I've put in

using System
using System.Collections

namespace Dem

/// <summary
/// Summary description for Classes
/// </summary
///
public class Class

string Message
public Class1(string message) {Message = message;


public class Class2: CollectionBas

public static void Main(

Class2 d = new Class2()
d.Add(new Class1("Hello"))
//d.Add("Hello")



public int Add(Class1 value

return List.Add(value)


public IEnumerator GetEnumerator(

// TODO: Add Class2.GetEnumerator implementatio
return null
 
G

Guest

Mark... thanks for the example, it illustrates what I THOUGHT was the case
but was trying to work around, but what I'm seein
is actually what I WANT to be the case. (Apart from the warning

But if you're not getting the warning, let me know. But you should do
with what I posted. I'm just looking for somebody to tell me that I'm doin
it wrong and that I can achieve the same thing properly by doing step
x, y and z - because I don't think I should be getting warnings
 
Ad

Advertisements

J

Jon Skeet [C# MVP]

songie D said:
This gives the warning on getenumerator: (although foreach calls the
correct version, i.e. the one I've put in)

foreach will only call the correct version if the *expression* used in
the foreach is of type Class2. For instance, you could do:

Class2 x = new Class2();

foreach (object o in x) // This would use your version of GetEnumerator
{
}

CollectionBase y = x;
foreach (object o in y) // This would use the base version
{
}
 
J

Jon Skeet [C# MVP]

songie D said:
Mark... thanks for the example, it illustrates what I THOUGHT was the case,
but was trying to work around, but what I'm seeing
is actually what I WANT to be the case. (Apart from the warning)

But if you're not getting the warning, let me know. But you should do,
with what I posted. I'm just looking for somebody to tell me that I'm doing
it wrong and that I can achieve the same thing properly by doing steps
x, y and z - because I don't think I should be getting warnings.

What you recently posted was different to your original question though
- you've posted a complete program where you hid GetEnumerator - you
didn't change the signature at all. In your first post, you indicated
that you were changing the method signature, in which case you
shouldn't get the warning.
 
G

Guest

I want to d
foreach(Class2 c in x
NOT
foreach(object c in x
where x is my custom collection class derived from CollectionBase, not a CollectionBase..

I can sort of see from what you're saying that if it is just a collectionbase, it will call th
standard version of GetEnumerator. But if it's my derived class, then it'll call my version
This is what I want. But should it REALLY be warning me about this? Shouldn't it be warnin
me about the opposite, i.e. if it was going to call the base class one, when I'd pu
my own in that was going to be ignored
 
G

Guest

I know, I'm quite confused about it all
But I think I've got it worked out. It's just the warning message that's bugging me.
 
J

Jon Skeet [C# MVP]

songie D said:
I want to do
foreach(Class2 c in x)
NOT:
foreach(object c in x)

Sure - but that change is irrelevant, as the cast is performed at
runtime anyway. It won't change which GetEnumerator method is being
called.
where x is my custom collection class derived from CollectionBase,
not a CollectionBase...

I think you misunderstand. The point is that the compiler works out
which method to call at compile-time, based on the type of the
*variable* x in this case - not based on the type of the object that
the value of x refers to at runtime.
I can sort of see from what you're saying that if it is just a
collectionbase, it will call the standard version of GetEnumerator.

No. I'm saying that if it's an instance of your derived class, but the
type of the *expression* is CollectionBase, then it'll call the base
class's version, which isn't what you want.
But if it's my derived class, then it'll call my version.

No it won't - not unless the *expression* is of your derived class type
at compile-time.
This is what I want. But should it REALLY be warning me about this?
Shouldn't it be warning me about the opposite, i.e. if it was going
to call the base class one, when I'd put my own in that was going to
be ignored?

I think you're still missing the point.

See http://www.pobox.com/~skeet/csharp/faq/#override.new
 
Ad

Advertisements

B

Bjorn Abelli

...
Does c# support overriding by name and not signature?

If you look closer to the message you get, it's not talking about
"overriding" at all, but "hiding"...
For instance I am building a custom collection class, that can
only take a certain type of object.
For this, I have added an override for add from the class view,
and changed it from
public int Add(object value)
to
public int Add(MyItemClass value)

This seems to work, but it generates a warning 'the new specifier is needed,
because this method hides ...[that of the base class].'
But even though I didn't think this would work to override the base class
because it's not the same signature...

Again, it's not "overriding", but "hiding", but in this case in *specific*
circumstances.

It actually *is* "sort of" the same signature, from a polymorphic view, as
you can assign a reference to an instance to a variable of its supertype.
Hence, this is allowed:

object o = new MyItemClass();

That is also applicable to what happens when you call a method. Say that you
*didn't* hide this method:
public int Add(object value)

Even if the variable was of the subtype....

MyItemClasso = new MyItemClass();

....you would still be able to use the following message:

instanceOfClass2.Add(o);

....but when you "hide" that method with...
public int Add(MyItemClass value)

....there could possibly be some ambiguity in which method actually is
intended to be called, but this is resolved at compile-time, as mentioned
elsewhere in the thread (by looking at the type of the *variable*, not of
the *instance*).

This was only a try to explain why the compiler issues the warning of
"hiding" the method.

// Bjorn A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top