Simon
Simon

Reputation: 34880

Why can I seal a class implementing an interface but cant seal a member?

Given this interface

public interface IMyInterface
{
    string Method1();
}

Why is this valid

public sealed class InheretedFromInterfaceSealed: IMyInterface
{
    public string Method1()
    {
        return null;
    }
}

But this isnt

public class InheretedFromInterfaceWithSomeSealed: IMyInterface
{
    public sealed string Method1()
    {
        return null;
    }
}

And yet it is a valid scenario for an abstract class

public abstract class AbstractClass
{
    public abstract string Method1();
}
public class InheretedFromAbstractWithSomeSealed: AbstractClass
{
    public sealed override string Method1()
    {
        return null;
    }
}

Upvotes: 2

Views: 2318

Answers (3)

Gee Law
Gee Law

Reputation: 56

Just a reminder that interface methods in C# cannot be sealed.

Consider the following code:

interface IFoo
{
    void Bar();
}
class Base : IFoo
{
    public void Bar() { Console.WriteLine("Base.Bar"); }
}
class Derived : Base, IFoo
{
    public new void Bar() { Console.WriteLine("Derived.Bar"); }
}

And then, if we have var d = new Derived(), we'll have:

  • d.Bar() writes Derived.Bar
  • ((Base)d).Bar() writes Base.Bar
  • ((IFoo)d).Bar() writes Derived.Bar
  • ((IFoo)(Base)d).Bar() writes Derived.Bar

The interface method Bar is overridden by the derived class. The method that is sealed is not the interface method, but a method of Base.

That is to say, an implicit implementation

class ImplicitImpl : IFoo
{
    public void Bar() { Blah; }
}

should be considered as the following semantically equivalent explicit implementation:

class ImplicitImplEquiv : IFoo
{
    public void Bar() { Blah; }
    void IFoo.Bar() { this.Bar(); }
}

If a derived class of ImplicitImplEquiv simply hides public void Bar with another public void Bar, calling ((IFoo)ref).Bar() will still invoke the ImplicitImplEquiv.Bar. But if the derived class also reinherits IFoo and provides a new implementation, the interface vtable will be different than that of ImplicitImplEquiv.

Upvotes: 0

Cody Gray
Cody Gray

Reputation: 244903

Every method in a class is sealed (NotOverridable in VB.NET) by default, unless you specifically declare it as virtual (Overridable in VB.NET).

As you've said, this is not the case with classes. You have to specifically indicate that you want to forbid inheriting from a class using sealed (or NotInheritable in VB.NET).

Upvotes: 2

user541686
user541686

Reputation: 210705

Because every method is by default sealed, unless it's virtual, or unless you don't say sealed on something that's already virtual and that you're overriding.

Upvotes: 6

Related Questions