How to process data including protected members using extension method in C#

171 views Asked by At

Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:

public class A
{
    protected int member1;
    public A(int value)
    {
        member1 = value;
    }
}

public class B : A
{
    public B (int value) : base(value)
    { }

    public void DoSomething()
    {
        Console.Write(member1 * member1);
    } 
}

class Program
{
    static void Main(string[] args)
    {
        A obj1 = new A(5);
        B obj2 = (B)obj1; // InvalidCastException
        obj2.DoSomething();   
    }
}

And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.

1

There are 1 answers

7
HappyBullying On BEST ANSWER

Here's my solution:

  1. Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
  2. Add protected static method which returns the protected member you need.
  3. Create an Extension class for your base class.
  4. In extension class create a private nested class.
  5. Inherit your nested class from your base class.
  6. Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
  7. Create extension method in extension class and call static method of nested class in it.

The sample code is shown below:

public class A
{
    protected int member1 = 0;
    public A() {}
    public A(int value)
    {
        member1 = value;
    }

    protected static int GetProtectedMember(A objA)
    {
        return objA.member1;
    }
}

public static class AExtensions
{
    public static void DoSomething(this A objA)
    {
        B.DoSomething(objA);
    }

    private class B : A
    {
        public static void DoSomething(A objA)
        {
            // objA.member1 // it's not allowed

            int protectedFromA = A.GetProtectedMember(objA);
            int sqr = protectedFromA * protectedFromA;
            Console.WriteLine(sqr);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        A obj1 = new A(5);
        obj1.DoSomething(); // 25
    }
}

This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.