Inheritance and overriding

M

Michael

Hello all,

Why this piece of code doesn't compile?

public class FStorage
{}

public class FSExcel : FStorage
{}

public abstract class IResultLine
{
public abstract void ToExcelLine(FStorage storage);
}


public class Foo
{
internal class ResultLine : IResultLine
{
public sealed override void ToExcelLine(FSExcel storage) {}
}
}


I have the next errors:

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_.ToExcelLine(AddIn.View.FileStorage.FSExcel)':
no suitable method found to override

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_' does not
implement inherited abstract member
'AddIn.View.IResultLine.ToExcelLine(AddIn.View.FileStorage.FStorage)'

Why do I have to pass a FStorage object, whereas ResultLine inherits
from IResultLine?

Thanks in advance

Mike
 
J

Jon Skeet [C# MVP]

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_.ToExcelLine(AddIn.View.FileStorage.FSExcel)':
no suitable method found to override

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_' does not
implement inherited abstract member
'AddIn.View.IResultLine.ToExcelLine(AddIn.View.FileStorage.FStorage)'

Why do I have to pass a FStorage object, whereas ResultLine inherits
from IResultLine?

To override a method, you have to specify *exactly* the same signature
(in terms of types and parameter modifiers; the parameter names can be
different).

Jon
 
R

Rudy Velthuis

Michael said:
public abstract void ToExcelLine(FStorage storage);
public sealed override void ToExcelLine(FSExcel storage) {}

I have the next errors:

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_.ToExcelLine(A
ddIn.View.FileStorage.FSExcel)': no suitable method found to override

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_' does not
implement inherited abstract member
'AddIn.View.IResultLine.ToExcelLine(AddIn.View.FileStorage.FStorage)'

Because the signature of both methods is not the same. What you are
trying to do is called "covariance", and C# does not support that for
method overriding. It is only supported for arrays and delegates (since
C# 2.0).
 
I

Ignacio Machin ( .NET/ C# MVP )

Hello all,

Why this piece of code doesn't compile?

public class FStorage
{}

public class FSExcel : FStorage
{}

public abstract class IResultLine
{
    public abstract void ToExcelLine(FStorage storage);

}

public class Foo
{
internal class ResultLine : IResultLine
{
    public sealed override void ToExcelLine(FSExcel storage) {}

}
}

I have the next errors:

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_.ToExcelLine(AddIn..­View.FileStorage.FSExcel)':
no suitable method found to override

'AddIn.ListOfControls.DerniersRapportsVisite.ResultLine_' does not
implement inherited abstract member
'AddIn.View.IResultLine.ToExcelLine(AddIn.View.FileStorage.FStorage)'

Why do I have to pass a FStorage object, whereas ResultLine inherits
from IResultLine?

Thanks in advance

Mike

Hi,

public abstract void ToExcelLine(FStorage storage);
public sealed override void ToExcelLine(FSExcel storage) {}

are not the same, they need to have the same signature.
Frankly what sense it has to declare a method virtual (which you do by
declaring it abstract) and later declared it as sealed ?
 
J

Jon Skeet [C# MVP]

On Apr 16, 1:30 pm, "Ignacio Machin ( .NET/ C# MVP )"

Frankly what sense it has to declare a method virtual (which you do by
declaring it abstract) and later declared it as sealed ?

That makes perfect sense to me. It's often entirely appropriate to say
"I don't want anyone overriding this method any further" but still
having it abstract in the base class.

It's similar to implementing an interface but marking the implementing
method as sealed, which is common in the Dispose pattern.

Personally I'd prefer to seal the whole derived class if possible, but
I have relatively extreme views on inheritance :)

Jon
 
B

Barry Kelly

Ignacio Machin ( .NET/ C# MVP ) wrote:

public abstract void ToExcelLine(FStorage storage);
public sealed override void ToExcelLine(FSExcel storage) {}
Frankly what sense it has to declare a method virtual (which you do by
declaring it abstract) and later declared it as sealed ?

It can make sense, on two grounds: correctness and performance.

If the descendant which overrides and seals the method needs to rely on
the implementation not changing for the rest of the implementation of
that descendant, it may seal the method. Further descendants won't be
able to override that particular method.

For the ancestor declaring the method, and intermediate ancestors,
virtual dispatch for the method will still work as expected.

In terms of performance: if a value that is statically known to be of a
type which declares a method to be sealed, or a descendant of a type
which declares a method to be sealed, virtual dispatch doesn't need to
be performed. A static call may be made instead.

-- Barry
 
M

Michael

To override a method, you have to specify *exactly* the same signature
(in terms of types and parameter modifiers; the parameter names can be
different).

Jon

OK, thanks for your reply, I didn't know that covariance couldn't be
applied here. Anyway I think that's a strange limitation, because I
don't see what would be a problem for the compiler to deduce that
FSExcel inherits from FStorage...

So I'll have to keep a cast to FSExcel in my function.
 
J

Jon Skeet [C# MVP]

OK, thanks for your reply, I didn't know that covariance couldn't be
applied here. Anyway I think that's a strange limitation, because I
don't see what would be a problem for the compiler to deduce that
FSExcel inherits from FStorage...

So I'll have to keep a cast to FSExcel in my function.

In this case it wouldn't be valid even if covariance/contravariance
*did* apply. An override should apply to *all* calls to the method -
so with covariance/contravariance you would be able to override with
*less* specific parameters and a *more* specific return type. You're
trying to override with a *more* specific parameter.

What would you expect to happen if someone called ToExcelLine with an
FStorage which *wasn't* an FSExcel?

Jon
 
B

Ben Voigt [C++ MVP]

Michael said:
OK, thanks for your reply, I didn't know that covariance couldn't be
applied here. Anyway I think that's a strange limitation, because I
don't see what would be a problem for the compiler to deduce that
FSExcel inherits from FStorage...

So I'll have to keep a cast to FSExcel in my function.

The problem is rather that the interface contract from the base class says
that you will accept any FStorage. You're now only providing an
implementation for the subset of FStorage objects which as FSExcel-derived.
This breaks the contract, and the compiler tells you so.
 

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

Similar Threads


Top