استدعاء حيوي أي وظيفة عن طريق تمرير اسم الدالة كسلسلة

StackOverflow https://stackoverflow.com/questions/801070

سؤال

وكيف يمكنني أتمتة عملية الحصول على مثيل خلق وظيفتها نفذت حيوي؟

والشكر

وتحرير: تحتاج خيار تمرير المعلمات أيضا. بفضل

هل كانت مفيدة؟

المحلول

هل كنت ترغب فقط في استدعاء منشئ parameterless لإنشاء المثال؟ هو نوع محدد كسلسلة أيضا، أو يمكنك جعلها وسيلة عام؟ على سبيل المثال:

// All error checking omitted. In particular, check the results
// of Type.GetType, and make sure you call it with a fully qualified
// type name, including the assembly if it's not in mscorlib or
// the current assembly. The method has to be a public instance
// method with no parameters. (Use BindingFlags with GetMethod
// to change this.)
public void Invoke(string typeName, string methodName)
{
    Type type = Type.GetType(typeName);
    object instance = Activator.CreateInstance(type);
    MethodInfo method = type.GetMethod(methodName);
    method.Invoke(instance, null);
}

أو

public void Invoke<T>(string methodName) where T : new()
{
    T instance = new T();
    MethodInfo method = typeof(T).GetMethod(methodName);
    method.Invoke(instance, null);
}

نصائح أخرى

لاستدعاء منشئ، Activator.CreateInstance سوف تفعل خدعة. أنه يحتوي على مجموعة من الزائدة، لتجعل حياتك أسهل.

إذا منشئ الخاص بك هو parameterless :

object instance = Activator.CreateInstance(type)

إذا كنت تحتاج المعلمات :

object instance =  Activator.CreateInstance(type, param1, param2)

لاستدعاء، طريقة، مرة واحدة لديك الكائن يمكنك الاتصال GetMethod للحصول على <ل أ href = "http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx" يختلط = "noreferrer"> طريقة ، ثم <وأ href = "HTTP: // msdn.microsoft.com/en-us/library/system.reflection.methodinfo.invoke.aspx "يختلط =" noreferrer "> Invoke (مع أو بدون معلمات) بالتمسك به. ينبغي كنت في حاجة إليها، واستدعاء تعطي لك أيضا قيمة الإرجاع وظيفة كنت استدعاء (أو لاغية إذا به في طريقة الفراغ)،

لعينة قليلا أكثر تفصيلا (صقها في التطبيق وحدة التحكم والذهاب):

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

namespace Test
{
    public static class Invoker
    {
        public static object CreateAndInvoke(string typeName, object[] constructorArgs, string methodName, object[] methodArgs)
        {
            Type type = Type.GetType(typeName);
            object instance = Activator.CreateInstance(type, constructorArgs);

            MethodInfo method = type.GetMethod(methodName);
            return method.Invoke(instance, methodArgs);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Default constructor, void method
            Invoker.CreateAndInvoke("Test.Tester", null, "TestMethod", null);

            // Constructor that takes a parameter
            Invoker.CreateAndInvoke("Test.Tester", new[] { "constructorParam" }, "TestMethodUsingValueFromConstructorAndArgs", new object[] { "moo", false });

            // Constructor that takes a parameter, invokes a method with a return value
            string result = (string)Invoker.CreateAndInvoke("Test.Tester", new object[] { "constructorValue" }, "GetContstructorValue", null);
            Console.WriteLine("Expect [constructorValue], got:" + result);

            Console.ReadKey(true);
        }
    }

    public class Tester
    {
        public string _testField;

        public Tester()
        {
        }

        public Tester(string arg)
        {
            _testField = arg;
        }

        public void TestMethod()
        {
            Console.WriteLine("Called TestMethod");
        }

        public void TestMethodWithArg(string arg)
        {
            Console.WriteLine("Called TestMethodWithArg: " + arg);
        }

        public void TestMethodUsingValueFromConstructorAndArgs(string arg, bool arg2)
        {
            Console.WriteLine("Called TestMethodUsingValueFromConstructorAndArg " + arg + " " + arg2 + " " + _testField);
        }

        public string GetContstructorValue()
        {
            return _testField;
        }
    }
}

وعلى افتراض أن الطريقة التي تريد أن تحتج لا يأخذ أية معلمات:

public void InvokeMethod(Type type, string methodName)
{
    object instance = Activator.CreateInstance(type);
    MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

    method.Invoke(instance, null);
}

وأعتقد أن مشكلتك هي قليلا عامة جدا هنا، وأنا توفير حل مع بعض الافتراضات هنا.

والافتراض: لديك typeName (سلسلة)، METHODNAME (سلسلة)، ومعلمة (من SomeType)

.
public static void InvokeMethod(string typeName, string methodName, SomeType objSomeType) {
      Type type = Type.GetType(typeName);
      if(type==null) {
        return;
      }
      object instance = Activator.CreateInstance(type); //Type must have a parameter-less contructor, or no contructor.   
      MethodInfo methodInfo =type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
      if(methodInfo==null) {
        return;
      }
      methodInfo.Invoke(instance, new[] { objSomeType });  
    } 

واسمحوا لي أن أعرف أعرف إذا كان لي افتراضات خاطئة.

لتمرير المعلمات حيوي هنا أخذت بارامس سلسلة [] وسائط، لأن وظائف مختلفة وعدد مختلف من المعلمات بذلك.

public void Invoke(string typeName,string functionName,params string[] args)
    {

     Type type = Type.GetType(typeName);
     dynamic c=Activator.CreateInstance(type);
     //args contains the parameters(only string type)
     type.InvokeMember(functionName,BindingFlags.InvokeMethod,null,c,args);   

    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top