Proxy pattern usually using for control access to other object with intercepting all calls. Let’s see example. We have printer class, that has Print() method. And we have Document class, that has attribute, that allow or disallow print this document. But current realization of Printer class can’t filter these document types and we shouldn’t change Printer class for some reasons (may be it has complex logic).

    public class Doc
    {
        public bool IsPrintable { get; set; }
        public string Content { get; set; }
        public Doc(string Content, bool IsPrintable)
        {
            this.Content = Content;
            this.IsPrintable = IsPrintable;
        }
    }    
    public interface IPrinter
    {
        public void Print(Doc doc);
    }

    public class Printer : IPrinter
    {
        public void Print(Doc d)
        {
            Console.WriteLine($"DATA: {d.Content}");
        }
    }

And now we received task from our analyst, he said, that now we can print only documents, that can be printed. In this situation, we can create proxy class PrinterProxy, that will check document types and decide, may we print this document or not.

    public class PrinterProxy : IPrinter
    {
        Printer p = new Printer();
        
        public void Print(Doc doc)
        {
            if (doc.IsPrintable) p.Print(doc); else p.Print(new Doc("--- Document is not available ---", true));
        }
    }

And now, when we try to print secret document, we will receive next result:

Doc doc1 = new Doc("Public Doc", true);
Doc doc2 = new Doc("Secret Doc", false);

var printer = new PrinterProxy();

printer.Print(doc1);
printer.Print(doc2);