简体   繁体   中英

C# Sealed Prevent a method to be derived

I'm trying to prevent my Base Class to derived one of its method, but it seems impossible to do it in the way I like, I assume I'm doing it wrong.

Could you help please ? :) I really want to use successfully the sealed keyword !

Here is a bit of code :

public class BaseClass
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public sealed void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

What happened is problematic, the keyword sealed isn't allow on a method which is in a first level of derivation. I only have one single derivation level, and what I'm looking for is avoiding MyMethod2 to be derived in the DerivedClass.

But it doesn't seem to be ok :/ Any advice or correction ?

Thanks in advance :)

EDIT : After many comments and lunch pause I'll try to explicit my question !

What I'm try to really do is to prevent my class to use one of the method "she" inherits. Some of you mentioned to use composition instead of inheritance, because it appeared I misunderstood its meaning.

I thought composition was only present in UML not in code. What a composition sounds like in C# code ?

If this is the first level, it is not overridable by derived class unless marked virtual or abstract .

public class BaseClass
{
    public virtual void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    public override void MyMethod1(string input){..}

    /// MyMethod2 is not overridable
}

Based on your comments below, it seems like what you really want is composition, not inheritance; that is to say that DerivedClass should be able to access some functionality on the BaseClass but should not be able to change it in any way. This may look like the below for your class example.

public class CompositeFunctionality
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
}
public class BaseClass
{
    private CompositeFunctionality composite = new CompositeFunctionality();
    public void MyMethod2(string input)
    {
        // this is accessible in the base class
        composite.MyMethod1();
    }
}

public class DerivedClass : BaseClass
{
    public void MyMethod3(string input)
    {
         // do whatever you want
         // but composite is not accessible here
    }
}

You can only seal a method/property that overrides a virtual method in a base class. Your MyMethod2 isn't virtual, so can't be sealed. In fact it's implicitly sealed by the fact it isn't virtual!

You need another level of inheritance to be able to use sealed . You can mark the method virtual in the base class, and override sealed it in the second class.

You could make the "absolute base" abstract, so it's not possible to instantiate it, then inherit from it to implement and seal it:

public abstract class VeryBaseClass
{
    public abstract void MyMethod2(string input);
}

public class BaseClass : VeryBaseClass
{
    public override sealed void MyMethod2(string input)
    {

    }
}

public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

But like @Jenish says , methods are sealed by default in C#.

On the contrary, to be able to override a method it must be marked virtual anyway, so your problem doesn't seem to be a problem at all. Just mark MyMethod1 as virtual so you can override it, and MyMethod2 will remain non-virtual so non-overridable at all.

The sealed keyword is implied to any method in a base class that isn't already virtual or abstract (and therefore overridable).

See this link on MSDN for more information

try like this..

class Base 
{
 public virtual void Test() { ... }
}

class Subclass1 : Base 
{
 public sealed override void Test() { ... }
}

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

I am renaming methods for a better understanding.

public class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
    //MethodoBeInherited should be available
    //MethodNotToBeInherited should not be available
}

The condition you want is not possible using this kind of hierarchy( Is a relationship ), because DervicedClass is a BaseClass. So on the rules of inheritance you are bound to have access to all BaseClass public methods.

But there is an alternative to solve this using - Has a relationship . Its not possible to inherit and achieve what you wanted as you will break the inheritance rule. So making the derived class composed of a base class you would be able to achieve it.

interface I
{
    void MethodToBeInherited(string input)
}

class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}

class DerivedClass : I
{
    public void MethodToBeInherited(string input)
    {
        b.MethodToBeInherited(input);
    }

    private BaseClass b;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM