error CS0621: virtual or abstract members cannot be private

C

cody

error CS0621: virtual or abstract members cannot be private

Why is that?

I mean wouldn't it sometimes be useful to do:


class Base
{
// nested class
class Derived : Base
{
private virtual Doit(){}
}

private abstract Doit();
}
 
F

Family Tree Mike

cody said:
error CS0621: virtual or abstract members cannot be private

Why is that?

I mean wouldn't it sometimes be useful to do:


class Base
{
// nested class
class Derived : Base
{
private virtual Doit(){}
}

private abstract Doit();
}


How would a subclass of Derived override a private function?
 
C

cody

Peter said:
I'm assuming in his example he meant for Derived.Doit() to be "override"
not "virtual", just as he obviously left out the "abstract" modifier for
"Base".

In that case, I'd say the answer is Derived is not meant to be
subclassed, at least not by a class that overrides Doit() (except
perhaps by a type nested within :) ). That would be consistent with the
accessibility, even if it's an awkward design.

Pete

Yes your are right, my mistake here is what I meant, exactly what you
were saying:

class Base
{
// nested class
class Derived : Base
{
private override void Doit() { }
}

private abstract void Doit();
}
 
C

cody

Peter said:
I doubt it.

The point of virtual methods is so that code outside the class can call
the method and get the polymorphic behavior. But, private methods
shouldn't be callable from code outside the class.

Sure, in your example, Derived can see the "Doit()" method in Base. But
no code outside Derived can see _Derived_'s implementation of Doit().
It seems like a very strange pattern to me to think that a) _any_ code
would be able to directly execute Derived's Doit() implementation, and
also that b) the only code that theoretically could do so would be in
the very class where Derived is declared (i.e. you will _never_ be in a
situation where the Derived type's method is used by code that has
knowledge only of the Base class, the usual reason we use polymorphism
in the first place).

Personally, to me it seems that even having a nested class inherit the
containing class is a step in the wrong direction to start with, never
mind the odd polymorphic construct. I would definitely suggest someone
reconsider their design if I saw code like that, unless there was a very
clear and obvious benefit.


Pete

Allowing *anybody* to derive from your class creates relationsships you
not not want most time as inheritance is the strongest relationship
between classes in existence.
So generally it is discouraged to make virtual methods public, instead
internal or protected should be used, so why not allowing private
virtual methods? To avoid things getting messy partial classes could be
used.
Have you an example of where you feel such a pattern might be useful?

Something like this, but certainly there are much more applications for
this.

abstract class Base
{
// nested class
class Derived1 : Base
{
private override void DoitInternal() { }
}

class Derived2 : Base
{
private override void DoitInternal() { }
}

public static Base Factory(string id)
{
if (id.Equals("Derived1"))
return new Derived1();
if (id.Equals("Derived2"))
return new Derived2();
// else if ..
}

private abstract void DoitInternal();

public void Doit()
{
DoitInternal();
}
}
 
C

cody

Peter said:
There are certainly schools of thought in OOP that feel that way. But
clearly, .NET/C# doesn't follow that philosophy. The OOP languages that
are in the mainstream all encourage inheritance.


Discouraged by whom? Public virtual members are quite common in OOP,
certainly in .NET, and interfaces (found in Java and C#, as well as
other languages) are basically _only_ public virtual members.

Yes it may be that this is not the opinion of everybody, just me and the
authors of some books I've read.
But I feel that most of the virtual methods in the .NET framework are
not public but protected (I didn't exactly count them so I may be wrong
here)
I'm not sure where you're suggesting partial classes would help.

If you use the pattern I showed and you have a lot of derived classes as
nested classes then partial classes certainly will help :)
How is your example superior to simply making the Base.Doit() method
virtual? It's not like you are somehow preventing someone from
sub-classing your Base class. They can't override your private virtual
method, but you've still got a public method they are going to _want_ to
override and instead are going to wind up hiding (which whatever you
think about public virtual methods seems to me to be much worse).

I could make the Base class constructor private so the nested classes
can still derive from it but nobody else.
I also feel that combining your factory and implementation in the same
class is awkward and unnecessary.

In the .NET framework this is used sometimes as in Image.FromFile().
If you want to hide _all_ of the
implementation, better to make the base class private to your factory as
well, the virtual method protected, and expose the API as an interface.

I'm not sure what you mean by "make the base class private to your factory".
I really can't speak for the C# designers. But, I suspect that if you
asked them, they would suggest that with the current rules, developers
are encouraged to keep their inheritance hierarchies and class
structures simpler.

I agree with that because if they wouldn't they would have changed them :)
I don't see anything fundamentally unworkable in
what you're suggesting, but it does seem awkward and likely to lead to
maintenance issues.

I cannot see how *restricting* who is allowed to override a method
impose maintenance issues.
The C# philosophy, at least originally, has been to keep things simple.
To prefer simple rules and simple structures, even if sometimes that
restricts what you can do. I suspect that's at least in part what's at
play here.

Pete

"at least originally" :) Good spoken, because now we have lambda
expressions, anonymous methods and delegates which are similar but
different.
And extension methods are what I really call a maintenance issue ^^
 

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