Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access an internal class from an external assembly?

Tags:

c#

class

Having an assembly which I cannot modify (vendor-supplied) which have a method returning an object type but is really of an internal type.

How can I access the fields and/or methods of the object from my assembly?

Keep in mind that I cannot modify the vendor-supplied assembly.

In essence, here's what I have:

From vendor:

internal class InternalClass   public string test; end class  public class Vendor   private InternalClass _internal;   public object Tag {get{return _internal;}} end class 

From my assembly using the vendor assembly.

public class MyClass {   public void AccessTest()   {     Vendor vendor = new Vendor();     object value = vendor.Tag;     // Here I want to access InternalClass.test   } } 
like image 438
Stécy Avatar asked May 28 '09 13:05

Stécy


People also ask

How do you access an internal class in another project?

You can use the InternalsVisibleTo attribute and provide the name of a specific assembly that can see the internal types in your assembly. That being said.. I think you are bordering on over-designing this. If the Settings class belongs only to Assembly A... don't put it in Assembly B...

How do you create an instance of an internal class?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass. InnerClass innerObject = outerObject.

Can internal class have public methods?

A public member of a class or struct is a member that is accessible to anything that can access the containing type. So a public member of an internal class is effectively internal.

What is internal access modifier?

Internal is one of the access modifiers that limits the access to types defined within the current project assembly. The default accessibility of classes and structs that are declared within a namespace or at the top level of a compilation unit and not within other types is internal.


2 Answers

I see only one case that you would allow exposure to your internal members to another assembly and that is for testing purposes.

Saying that there is a way to allow "Friend" assemblies access to internals:

In the AssemblyInfo.cs file of the project you add a line for each assembly.

[assembly: InternalsVisibleTo("name of assembly here")] 

this info is available here.

Hope this helps.

like image 88
zonkflut Avatar answered Sep 18 '22 11:09

zonkflut


Without access to the type (and no "InternalsVisibleTo" etc) you would have to use reflection. But a better question would be: should you be accessing this data? It isn't part of the public type contract... it sounds to me like it is intended to be treated as an opaque object (for their purposes, not yours).

You've described it as a public instance field; to get this via reflection:

object obj = ... string value = (string)obj.GetType().GetField("test").GetValue(obj); 

If it is actually a property (not a field):

string value = (string)obj.GetType().GetProperty("test").GetValue(obj,null); 

If it is non-public, you'll need to use the BindingFlags overload of GetField/GetProperty.

Important aside: be careful with reflection like this; the implementation could change in the next version (breaking your code), or it could be obfuscated (breaking your code), or you might not have enough "trust" (breaking your code). Are you spotting the pattern?

like image 43
Marc Gravell Avatar answered Sep 21 '22 11:09

Marc Gravell