should this be allowed?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

look at the sampl

<pre

using System

class Bas


public virtual void Print(

Console.WriteLine( "Executing the base." )




class Derived : Bas


private new void Print(

Console.WriteLine( "Executing the derived." )
base.Print()


public void Print2(

Print()




class MainAp


static void Main(


Derived obj = new Derived()
obj.Print()

Console.WriteLine( "" )

obj.Print2()





</pre

now I basically have 2 versions of Print defined for Derived. one for external, one for internal. should the compiler actually allow this in the first place?
 
Daniel Jin said:
look at the sample

now I basically have 2 versions of Print defined for Derived. one for
external, one for internal. should the compiler actually allow this
in the first place?

Absolutely. The point of "new" is that it's defining a completely
different method. Whether or not it's a good idea to use this fact
arbitrarily is a different matter.
 
The "new" keyword tells the compiler that you are defining a "new" method.
So, this makes perfect sense.
The compiler won't allow the restriction from public to private if you
replace "new" by "override".

Bruno.

Daniel Jin said:
look at the sample

<pre>

using System;

class Base
{

public virtual void Print()
{
Console.WriteLine( "Executing the base." );
}

}

class Derived : Base
{

private new void Print()
{
Console.WriteLine( "Executing the derived." );
base.Print();
}

public void Print2()
{
Print();
}

}

class MainApp
{

static void Main()
{

Derived obj = new Derived();
obj.Print();

Console.WriteLine( "" );

obj.Print2();

}

}

</pre>

now I basically have 2 versions of Print defined for Derived. one for
external, one for internal. should the compiler actually allow this in the
first place?
 
----- Jon Skeet [C# MVP] wrote: ----
Absolutely. The point of "new" is that it's defining a completely
different method. Whether or not it's a good idea to use this fact
arbitrarily is a different matter

Just seemed a little odd to me since Print from base class isn't hidden because the difference in visibility. Wouldn't it be better if the compiler at least generated a warning? say hypothetically, I wanted to make the new Print() public in Derived, but for some reason I forgot to mark it with public, so it defaulted to private. compiler doesn't complain. now I call Derived.Print(), but the base method executes. It'd be probably very easy to spot a mistake like this, but still, warning would be nice.
 
"new" methods are a rather dangerous feature IMO. So, you have to be careful
when you use it. Given its semantics, it is difficult for the compiler to
give you this kind of warning.

I try to restrict the use of new to cases where the new method performs
exactly the same thing as the method in the superclass but has a different
return type. The typical pattern is the following:

class BaseContainer { }
class BaseElement
{
private BaseContainer _container;
public BaseContainer Container { get { return _container; } }
}

class DerivedContainer : BaseContainer {}
class DerivedElement : BaseElement
{
public new DerivedContainer Container { get { return
(DerivedContainer)base.Container; } }
}

The idea is to get a correctly typed API in the derived API. (this is called
type covariance and languages like Eiffel support it).

But I don't allow any other use of new methods, because anything else
(redefining a method to give it different semantics than what it has in the
base class) is just heading for trouble. If the two methods do different
things, you get different results depending on whether you call them from a
BaseXxx or a DerivedXxx (the types that the compiler sees, not the runtime
types), and this can lead to very tricky bugs.

Bruno.

Daniel Jin said:
----- Jon Skeet [C# MVP] wrote: -----
Absolutely. The point of "new" is that it's defining a completely
different method. Whether or not it's a good idea to use this fact
arbitrarily is a different matter.

Just seemed a little odd to me since Print from base class isn't
hidden because the difference in visibility. Wouldn't it be better if the
compiler at least generated a warning? say hypothetically, I wanted to make
the new Print() public in Derived, but for some reason I forgot to mark it
with public, so it defaulted to private. compiler doesn't complain. now I
call Derived.Print(), but the base method executes. It'd be probably very
easy to spot a mistake like this, but still, warning would be nice.
 

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

Back
Top