Home > Enterprise >  Is there a way to raise an error at compile-time if I don't override the virtual method?
Is there a way to raise an error at compile-time if I don't override the virtual method?

Time:09-05

Please note in advance that this is a code written for learning purposes. Please look at the flow rather than the direct implementation :D


I have a FileHandler that simply reads and writes files.

public class FileHandler : IReadAndWriteHandler
{
    private const string Path = @"C:\Temp\tempFile.txt";
    
    public void Write(string message)
    {
        using var writer = new StreamWriter(Path);
        writer.WriteLine(message);
    }

    public string Read()
    {
        using var reader = new StreamReader(Path);
        
        return  reader.ReadLine();
    }
}
public interface IReadAndWriteHandler
{
    public void Write(string message);
    public string Read();
}

To extend the functionality, we decide to use the Decorator pattern. So, I wrote a decorator like this:

public abstract class HandlerDecorator : IReadAndWriteHandler
{
    private readonly IReadAndWriteHandler _handler;

    protected HandlerDecorator(IReadAndWriteHandler handler)
    {
        _handler = handler;
    }
    
    public virtual void Write(string message)
    {
        _handler.Write(message);
    }

    public virtual string Read()
    {
        return _handler.Read();
    }
}

Now we can extend our functionality by inheritance our decorator. I wrote an EncryptionHandlerDecorator that does encryption. But I accidentally forgot to override Read().

public class EncryptionHandlerDecorator : HandlerDecorator
{
    public EncryptionHandlerDecorator(IReadAndWriteHandler handler)
        : base(handler)
    {
        
    }

    public override void Write(string message)
    {
        base.Write(Encrypt(message));
    }

    private static string Encrypt(string message) => $"Encrpyt({message})";
}

However, It doesn't raise an error at compile-time, so it works fine. Very sadly, when you actually use it, the encrypted content is read, so it's wrong code.

To solve this, there is a way to directly implement one by one without using an abstract class, but that is not the point of this question right now.

If I don't override a virtual method defined in an abstract class, is there a way to raise an error at compile-time like an interface?

CodePudding user response:

You're probably looking for abstract methods, which requires derived classes to implement the function. However, you'll need to define internal scoped functions, so derived classes can write to the handler itself, as the base implementation will no longer be available to it.

public abstract class HandlerDecorator : IReadAndWriteHandler
{
    private readonly IReadAndWriteHandler _handler;

    protected HandlerDecorator(IReadAndWriteHandler handler)
    {
        _handler = handler;
    }
    
    public abstract void Write(string message);

    public abstract string Read();

    internal void WriteRaw(string message)
    {
        _handler.Write(message);
    }

    internal string ReadRaw()
    {
        return _handler.Read();
    }
}
  • Related