Выполнить метод из загруженной сборки [дубликат]

Давайте перепишем ваш код следующим образом:

x = 1
y = [x]
z = y * 4

myList = [z] * 3

После этого запустите следующий код, чтобы сделать все более понятным. Что делает код, в основном печатает id s полученных объектов, которые

Вернуть «идентификатор» объекта

blockquote >

и поможет нам идентифицировать их и проанализировать, что происходит:

print("myList:")
for i, subList in enumerate(myList):
    print("\t[{}]: {}".format(i, id(subList)))
    for j, elem in enumerate(subList):
        print("\t\t[{}]: {}".format(j, id(elem)))

И вы получите следующий результат:

x: 1
y: [1]
z: [1, 1, 1, 1]
myList:
    [0]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528
    [1]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528
    [2]: 4300763792
        [0]: 4298171528
        [1]: 4298171528
        [2]: 4298171528
        [3]: 4298171528

Итак, теперь давайте шаг за шагом. У вас есть x, который является 1, и единственным списком элементов y, содержащим x. Ваш первый шаг - y * 4, который даст вам новый список z, который в основном [x, x, x, x], т. Е. Создает новый список, который будет содержать 4 элемента, которые являются ссылками на исходный объект x. Чистый шаг очень похож. В основном вы делаете z * 3, который является [[x, x, x, x]] * 3 и возвращает [[x, x, x, x], [x, x, x, x], [x, x, x, x]] по той же причине, что и для первого шага.

23
задан w128 3 July 2014 в 09:28
поделиться

4 ответа

использовать отражение, чтобы проверить, есть ли у него метод «CustomType MyMethod (byte [] a, int b)» и называть его или выдавать исключение иначе

Ваш текущий код не выполняет это требование. Но вы можете довольно легко с чем-то вроде этого:

var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(byte[]), typeof(int) });
if (methodInfo == null) // the method doesn't exist
{
    // throw some exception
}

var o = Activator.CreateInstance(t);

var result = methodInfo.Invoke(o, params);

Достаточно ли это, или есть лучшие / более быстрые / короткие способы?

As насколько я заинтересован, это лучший способ, и на самом деле нет ничего более быстрого для каждого из них.

Что относительно конструкторов, учитывая, что эти методы не являются статическими, можно ли их просто игнорировать?

Вам все равно придется создать экземпляр t, как показано в моем примере. Это будет использовать конструктор по умолчанию без аргументов. Если вам нужно передать аргументы, вы можете увидеть документацию MSDN и изменить его как таковой.

8
ответ дан Mike Perrenoud 20 August 2018 в 16:37
поделиться

Вы можете использовать динамический тип, который будет разрешен во время выполнения.

Type type = Type.GetType(className, true);
dynamic instance = Activator.CreateInstance(type);
var response = instance.YourMethod();
2
ответ дан Andres Jaramillo Ortiz 20 August 2018 в 16:37
поделиться
5
ответ дан Talha 20 August 2018 в 16:37
поделиться

Поскольку это, кажется, популярный вопрос, вот полный пример исходного кода о том, как это сделать.

Предположим, что у нас есть сборка образцов, MyAssembly.dll , с класс MyClass . Мы хотим динамически загрузить его и вызвать его методы. Код MyAssembly :

namespace MyAssembly
{
    public class MyClass
    {
        public int X { get; set; }
        public int Y { get; set; }

        public MyClass(int initialX, int initialY)
        {
            X = initialX;
            Y = initialY;
        }

        public int MyMethod(int count, string text)
        {
            Console.WriteLine("This is a normal method.");
            Console.WriteLine("Count: {0}", count);
            Console.WriteLine("Text: {0}", text);

            return this.X + this.Y;
        }

        public static void StaticMethod(int count, float radius)
        {
            Console.WriteLine("This is a static method call.");
            Console.WriteLine("Count: {0}", count);
            Console.WriteLine("Radius: {0}", radius);
        }
    }
}

Сначала мы хотели бы создать экземпляр класса с помощью конструктора MyClass(int initialX, int initialY), а затем вызвать метод public int MyMethod(int count, string text). Вот как вы это делаете из другого проекта (например, консольного приложения):

static void Main(string[] args)
{
    //
    // 1. Load assembly "MyAssembly.dll" from file path. Specify that we will be using class MyAssembly.MyClass
    //
    Assembly asm = Assembly.LoadFrom(@"C:\Path\MyAssembly.dll");
    Type t = asm.GetType("MyAssembly.MyClass");

    //
    // 2. We will be invoking a method: 'public int MyMethod(int count, string text)'
    //
    var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(int), typeof(string) });
    if (methodInfo == null)
    {
        // never throw generic Exception - replace this with some other exception type
        throw new Exception("No such method exists.");
    }

    //
    // 3. Define parameters for class constructor 'MyClass(int initialX, int initialY)'
    //
    object[] constructorParameters = new object[2];
    constructorParameters[0] = 999; // First parameter.
    constructorParameters[1] = 2;   // Second parameter.

    //
    // 4. Create instance of MyClass.
    //
    var o = Activator.CreateInstance(t, constructorParameters);

    //
    // 5. Specify parameters for the method we will be invoking: 'int MyMethod(int count, string text)'
    //
    object[] parameters = new object[2];
    parameters[0] = 124;            // 'count' parameter
    parameters[1] = "Some text.";   // 'text' parameter

    //
    // 6. Invoke method 'int MyMethod(int count, string text)'
    //
    var r = methodInfo.Invoke(o, parameters);
    Console.WriteLine(r);
}

Вызов статического метода public static void StaticMethod(int count, float radius) выглядит так:

var methodInfoStatic = t.GetMethod("StaticMethod");
if (methodInfoStatic == null)
{
    // never throw generic Exception - replace this with some other exception type
    throw new Exception("No such static method exists.");
}

// Specify parameters for static method: 'public static void MyMethod(int count, float radius)'
object[] staticParameters = new object[2];
staticParameters[0] = 10;
staticParameters[1] = 3.14159f;

// Invoke static method
methodInfoStatic.Invoke(o, staticParameters);
19
ответ дан w128 20 August 2018 в 16:37
поделиться
  • 1
    В примере вашего статического метода, откуда появился o? methodInfoStatic.Invoke(o, staticParameters); – theonlygusti 29 October 2016 в 15:28
  • 2
    @theonlygusti прошло некоторое время с тех пор, как я это написал, но IIRC o такой же, как в приведенном выше примере, но поскольку это статический метод, если я не ошибаюсь, вы можете просто передать null вместо o. – w128 29 October 2016 в 17:33
Другие вопросы по тегам:

Похожие вопросы: