1

I'm trying to understand the reflection C#, specifically loading a third-party dll in my program. I created a simple dll:

namespace testclass
{
    public class Class1
    {
        private string f;
        public string f1 { get; set; }
    }

    public class Class2
    {
        public static int f2 = 0;
        public static string f1 { get; set; }

        static Class2()
        {
            Console.WriteLine("1st string");
        }

        public  void runme()
        {
            Console.WriteLine("2nd string");       
        }
    }
}

And load it to my program:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

class program
{
   static void Main()
    {    
        Assembly assembly;
        assembly = Assembly.LoadFrom(@"D:\user\ClassLibrary1.dll");
        var exporttypes = assembly.GetExportedTypes();
        foreach (var types in exporttypes)
        {
            var fields = types.GetFields();
            foreach (var fi in fields)
            {
                if (fi.Name == "f2")
                {
                    fi.SetValue(exporttypes, 2);
                }
            }
            var m1 = types.GetMethods();
            for (int i = 0; i < m1.Length; i++)
            {
                if (m1[i].Name == "runme")
                {
                    m1[i].Invoke(types, null);
                }
            }
        }

        Console.ReadKey();
    }
}

The problem is that when you try to call the method 'runme', the compiler gives an exception if 'runme' is not static. I would like to understand that in this case you need to pass as the first argument to invoke

Glen Thomas
  • 10,190
  • 5
  • 33
  • 65

3 Answers3

4

To invoke a non-static method using reflection, you must create an instance of the type and pass that as the first argument to Invoke.

So in terms of your code, this could be

if (m1[i].Name == "runme")
{
    var inst = Activator.CreateInstance(types);
    m1[i].Invoke(inst, null);
}

Note, that will only work because that type has a parameterless constructor, and is the most basic way of creating an instance from a type, many others exist.

Jamiec
  • 133,658
  • 13
  • 134
  • 193
1

You need to create an instance of an object to call non-static methods on it:

// Only works if there's a default ctor:
var instance = Activator.CreateInstance(types);

Then you pass the instance to the non-static method you're trying to call:

m1[i].Invoke(instance, null);

Note: Your variable types should really be singular: theType, for example.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

You would need to create an instance.

I believe the syntax would be

var instance = Activator.CreateInstance(types).
m1[i].Invoke(instance, null);
Derek Van Cuyk
  • 953
  • 7
  • 23