3

I'm using a function from an external assembly that returns an object which is a list of an internal class and I cannot find a way to cast it in my code.

Code in the external assembly:

namespace AssemblyNamespace
{
    internal class InternalClass
    {
        protected internal byte b;
        protected internal int i;
    }

    public class PublicClass
    {
        public object PublicMethod()
        {
             return new List<InternalClass>();
        }
    }
}

My code:

using AssemblyNamespace;

static void Main()
{
    PublicClass P = new PublicClass();
    object obj = new object();

    obj = P.PublicMethod();

    // Is it possible to cast obj?
}

Is it possible to cast obj through reflection or something else? I took a look at question C# - How to access internal class from external assembly but could not find a way to use their suggestions.

Community
  • 1
  • 1
  • What do you want to cast it to? – Alex Krupka Dec 08 '16 at 20:00
  • To the same type of `InternalClass`, so I can access `b` and `i`. – Guilherme Serafina Dec 08 '16 at 20:03
  • I always thought one could not expose internal types as return values of public functions? as per documentation, "you cannot have a public method M that returns a class C unless C is also public", [here](https://msdn.microsoft.com/en-us/library/ms173121.aspx) - is there a loophole for generics? – Cee McSharpface Dec 08 '16 at 20:04
  • Find out who wrote the assembly, yell at them. But really I think you'll have to do some trickery like serialize the object, then deserialize it into a type you own. – Jonesopolis Dec 08 '16 at 20:05
  • 1
    check out this: http://stackoverflow.com/questions/38057618/internal-class-masked-by-object. I did not try it, but is that not a case where `dynamic` keyword would help? are you sure `b` and `i` are fields, not properties? – Cee McSharpface Dec 08 '16 at 20:07

1 Answers1

3

You should not expose an internal type from a public API...and you are returning an empty list from PublicMethod() so there is no InternalClass object to access.

But if the PublicMethod() actually returns an InternalClass object...:

public class PublicClass
{
    public object PublicMethod()
    {
        return new List<InternalClass>() { new InternalClass() { b = 10 } };
    }
}

...you could access its fields through reflection like this:

static void Main()
    {
        PublicClass P = new PublicClass();
        System.Collections.IList list = P.PublicMethod() as System.Collections.IList;
        object internalObject = list[0];
        FieldInfo fi = internalObject.GetType().GetField("b", BindingFlags.NonPublic | BindingFlags.Instance);
        byte b = (byte)fi.GetValue(internalObject);
        Console.WriteLine(b);
    }

The above sample code will print "10", i.e. the value of the byte "b" field of the InternalClass object returned from the PublicMethod(), to the Console.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Yeah, the real `PublicMethod()` actually returns a usable object. It's just that I wrote this example from scratch and forgot to put something there... – Guilherme Serafina Dec 09 '16 at 10:41