1

I have this C# code in an external assembly:

namespace Fancy
{
  internal class Foo
  {
    public static void Window(string title, Foo.WindowFunction sceneViewFunc, int order)
    {}
    
    public delegate void WindowFunction(float x, float y);
  }
}

And I have my code:

class A 
{
  public static void Draw(float x, float y) 
  {
     // impl
  }

  static void Main(string[] args)
  {
     var newWindow = ?;
  }
}

I want to call Fancy.Foo.Window() like

Fancy.Foo.Window("Window Name", new Foo.WindowFunction(A.Draw), 450);

inside my A class through Reflection.

How can I do it? Tried lot of different options no success :/

Lothav
  • 183
  • 7
  • Fancy.Foo.Window("Window Name", new Foo.WindowFunction(Draw), 450); Would work if internal class Foo changed to class Foo – Naveed Yousaf Aug 20 '20 at 05:40
  • Why is `Foo` marked `internal` if you want to invoke it from other assemblies? Can't you just make it `public`? – Streamline Aug 20 '20 at 05:41

2 Answers2

0

The documentation defines internal access modifier as follows

The type or member can be accessed by any code in the same assembly, but not from another assembly.

Not being able to access from outside of the assembly is the default and expected behaviour. But you can do that in multiple ways. If you have access to the source of the external assembly. You can mark your current assembly as a friend of the external assembly as shown below and recmpile it.

[assembly: InternalsVisibleTo("<Your assembly name>")]

Considering that you might not always have access to the source of external assembly, the same can be done using reflection by loading the assembly, creating an instance of the class and fetching the Non-Public members on the internal type. See how to access internal class using reflection. See also other ways to use internal class of another assembly.

Using reflection on external/third-party assemblies comes with its own caveats as the source of the assembly may change at any point in time, breaking your code.

Sai Gummaluri
  • 1,340
  • 9
  • 16
0

Below is the code: ClassLibrary1:

using System;
namespace ClassLibrary1
{
public class Foo
{
    public static void Window(string title, WindowFunction sceneViewFunc, int order)
    {
        Console.WriteLine("Foo Window");
    }

    public delegate void WindowFunction(float x, float y);
}
}

Main Program.cs

using System;
using static ClassLibrary1.Foo;

namespace Algorithums
{
public class Program
{
     public static void Draw(float x, float y)
     {
        // impl
     }
    public static void Main(string[] args)
    {
        RegisterWindowFunctionActionAndWindow("Window Name", 450);        
        Console.WriteLine("Hello World!");
        Console.ReadLine();
    }

    public static void RegisterWindowFunctionActionAndWindow(string WindowName, int order)
    {
        var jsoType = Type.GetType("ClassLibrary1.Foo,ClassLibrary1");
        var jso = Activator.CreateInstance(jsoType);
        var mi = typeof(Program).GetMethod("Draw");
        var d = Delegate.CreateDelegate(typeof(WindowFunction), mi);
        var mi0 = jsoType.GetMethod("Window", new[] { typeof(string), typeof(WindowFunction), typeof(int) });
        mi0.Invoke(jso, new object[] { WindowName, d, order });
    }
}
Vikas Garg
  • 202
  • 2
  • 8