开发者

Sealed method in C#

I am a newbie in C#.I am reading about Sealed k开发者_开发技巧eyword.I have got about sealed class.I have read a line about Sealed method where we can make Sealed method also.The line was (By declaring method as sealed, we can avoid further overriding of this method.) I have created a demo but didn't understand that the meaning of above line and sealed method use. Below is my code:-

using System;

namespace ConsoleApplication2
{
    class Program:MyClass
    {
        public override sealed void Test()
        {
            Console.WriteLine("My class Program");
        }
        static void Main(string[] args)
        {
            Program obj = new Program();
            obj.Test();
            Console.ReadLine();
        }
    }

    class MyClass
    {
        public virtual void Test()
        {
            Console.WriteLine("My class Test");
        }
    }


}

Please tell me why we use Sealed methods and what are the advantages of Sealed methods.


Well, you are testing with only two levels of inheritance, and you are not getting to the point that you're "further overriding" a method. If you make it three, you can see what sealed does:

class Base {
   public virtual void Test() { ... }
}
class Subclass1 : Base {
   public sealed override void Test() { ... }
}
class Subclass2 : Subclass1 {
   public override void Test() { ... } // Does not compile!
   // If `Subclass1.Test` was not sealed, it would've compiled correctly.
}


A sealed class is a class which cannot be a base class of another more derived class.

A sealed method in an unsealed class is a method which cannot be overridden in a derived class of this class.

Why do we use sealed methods? What are the advantages of sealed methods?

Well, why do you use virtual methods? To provide a point at which behaviour of a class can be customized. So why do you use sealed methods? To provide a point at which you are guaranteed that no further changes will occur in the behaviour of any derived class with respect to this method.

Points where the behaviour of a class can be customized are useful but dangerous. They are useful because they enable derived classes to change behaviour of the base class. They are dangerous... wait for it... because they enable derived classes to change behaviour of the base class. Virtual methods basically allow third parties to make your classes do crazy things that you never anticipated or tested.

I like writing code that does what I anticipate and what I tested. Sealing a method allows you to continue to allow parts of the class to be overridden while making the sealed methods have guaranteed, testable, stable behaviour that cannot be further customized.


Well, you'd only use "sealed" on a method if you didn't want any derived classes to further override your method. Methods are sealed by default, if they're not declared as virtual and not overriding another virtual method. (In Java, methods are virtual by default - to achieve "default" C# behaviour you have to mark a method as final.)

Personally I like to control inheritance carefully - I prefer whole classes to be sealed where possible. However, in some cases you still want to allow inheritance, but ensure that some methods aren't overridden further. One use might be to effectively template the method, e.g. for diagnostics:

public sealed override void Foo(int x)
{
    Log("Foo called with argument: {0}", x);
    FooImpl(x);
    Log("Foo completed");
}

protected abstract void FooImpl(int x);

Now subclasses can't override Foo directly - they'd have to override FooImpl, so our behaviour will always be executed when other code calls Foo.

The templating could be for other reasons of course - for example to enforce certain aspects of argument validation.

In my experience sealed methods aren't used terribly often, but I'm glad the ability is there. (I just wish classes were sealed by default, but that's another conversation.)


Now if you declare a subclass of Program you won't be able to override the Test method, that's the point.

In most cases you won't need sealed methods but they can prove themselves useful when you're developing a base class for some plugin system that third-party developers have to extend in order to create their own plugin. You can keep some service data like plugin name and whether it is enabled and use sealed methods and properties to do it, so plugin developers won't mess with it. That's one case when sealed members come handy


Sealed Methods

Sealed method is used to define the overriding level of a virtual method.

Sealed keyword is always used with override keyword.

Practical demonstration of sealed method

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sealed_method
{
    class Program
    {
        public class BaseClass
        {

            public virtual void Display()
            {
                Console.WriteLine("Virtual method");
            }
        }

       public class DerivedClass : BaseClass
        {
            // Now the display method have been sealed and can;t be overridden
            public override sealed void Display()
            {
                Console.WriteLine("Sealed method");
            }
        }

       //public class ThirdClass : DerivedClass
       //{

       //    public override void Display()
       //    {
       //        Console.WriteLine("Here we try again to override display method which is not possible and will give error");
       //    }
       //}

        static void Main(string[] args)
        {

            DerivedClass ob1 = new DerivedClass();
            ob1.Display();

            Console.ReadLine();
        }
    }
}


First of all, let's start with a definition; sealed is a modifier which if applied to a class make it non-inheritable and if applied to virtual methods or properties makes them non-ovveridable.

public sealed class A { ... }
public class B 
{
    ...
    public sealed string Property { get; set; }
    public sealed void Method() { ... }
}

An example of its usage is specialized class/method or property in which potential alterations can make them stop working as expected (for example, the Pens class of the System.Drawing namespace).

...
namespace System.Drawing
{
    //
    // Summary:
    //     Pens for all the standard colors. This class cannot be inherited.
    public sealed class Pens
    {
        public static Pen Transparent { get; }
        public static Pen Orchid { get; }
        public static Pen OrangeRed { get; }
        ...
    }
}

Because a sealed class cannot be inherited, it cannot be used as base class and by consequence, an abstract class cannot use the sealed modifier. It's also important to mention that structs are implicitly sealed.

Example

public class BaseClass {
    public virtual string ShowMessage()
    {
        return "Hello world";
    }
    public virtual int MathematicalOperation(int x, int y)
    {
        return x + y;
    }
}
public class DerivedClass : BaseClass {
    public override int MathematicalOperation(int x, int y) 
    {
        // since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
        return x - y;
    }
    public override sealed string ShowMessage()
    {
        // since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
        return "Hello world sealed";
    }
}
public class DerivedDerivedClass : DerivedClass
{
    public override int MathematicalOperation(int x, int y)
    {
        // since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
        return x * y;
    }
    public override  string ShowMessage() { ... } // compile error
}
public sealed class SealedClass: BaseClass {
    public override int MathematicalOperation(int x, int y)
    {
        // since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
        return x * y;
    }
    public override string ShowMessage()
    {
        // since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
        return "Hello world";
    }
}
public class DerivedSealedClass : SealedClass
{
    // compile error
}

Microsoft documentation

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed


C# has it because Java has an identical feature (final methods). I've never seen a legitimate use.

If you don't want to permit extension, the whole class should be marked sealed and not just one method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜