C # 'da bir dizeden fonksiyon çağırmak


145

Php biliyorum gibi bir arama yapmak mümkün:

$function_name = 'hello';
$function_name();

function hello() { echo 'hello'; }

Bu .Net'te mümkün mü?


2
Yönteminizin de olması gerektiğini gördüm public.
zapoo

Yanıtlar:


268

Evet. Yansımayı kullanabilirsiniz. Bunun gibi bir şey:

Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(TheCommandString);
theMethod.Invoke(this, userParameters);

56
Ve bu da "System.Reflection kullanımı;"
jptsetung

1
Bu, parametre ile bir işlevi çağırmak için de kullanılabilir mi: örn. String f = "method (parametre1, parametre2)";
Thunder

Yanıt için @ottobar teşekkürler. Ben de ne aradığını bulamıyorum: C # kodumda bir SQL skaler işlevi kullanmak gerekiyordu. Nasıl arayabilirim?
Chagbert

1
FYI, aşırı yüklenmiş yöntemleriniz varsa işe yaramaz.
Sean O'Neil

Yukarıdaki kodla - Çağrılan yöntemin erişim değiştiricisi olmalıdır - PUBLIC. Herkese açık değilse lütfen Bağlayıcı bayrakları kullanın - BindingFlags.NonPublic | Type thisType = this.GetType(); MethodInfo theMethod = thisType.GetMethod(TheCommandString, BindingFlags.NonPublic | BindingFlags.Instance); theMethod.Invoke(this, userParameters);
BindingFlags.Instance

75

Dinamik yöntem çağırma işlemi yaparak yansıma kullanarak bir sınıf örneğinin yöntemlerini çağırabilirsiniz:

Bir gerçek örnekte merhaba adında bir yönteminiz olduğunu varsayalım (this):

string methodName = "hello";

//Get the method information using the method info class
 MethodInfo mi = this.GetType().GetMethod(methodName);

//Invoke the method
// (null- no parameter for the method call
// or you can pass the array of parameters...)
mi.Invoke(this, null);

1
"string" sınıfından yöntemler ne olacak? çerçeve 4'ü kullanma
Leandro

36
class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(MyReflectionClass);
            MethodInfo method = type.GetMethod("MyMethod");
            MyReflectionClass c = new MyReflectionClass();
            string result = (string)method.Invoke(c, null);
            Console.WriteLine(result);

        }
    }

    public class MyReflectionClass
    {
        public string MyMethod()
        {
            return DateTime.Now.ToString();
        }
    }

bu sınıfa bağımlı değildir
Leandro

Ve yöntem geçersiz mi?
Kiquenet

2

Hafif bir teğet - (iç içe!) İşlevler içeren bir ifade dizesinin tamamını ayrıştırmak ve değerlendirmek istiyorsanız, NCalc'i ( http://ncalc.codeplex.com/ ve nuget) düşünün

Ör. proje belgelerinden biraz değiştirildi:

// the expression to evaluate, e.g. from user input (like a calculator program, hint hint college students)
var exprStr = "10 + MyFunction(3, 6)";
Expression e = new Expression(exprString);

// tell it how to handle your custom function
e.EvaluateFunction += delegate(string name, FunctionArgs args) {
        if (name == "MyFunction")
            args.Result = (int)args.Parameters[0].Evaluate() + (int)args.Parameters[1].Evaluate();
    };

// confirm it worked
Debug.Assert(19 == e.Evaluate());

EvaluateFunctionDelege içinde mevcut işlevinizi çağırırsınız.


0

Aslında Windows Workflow 4.5 üzerinde çalışıyorum ve bir temsilci bir statemachine başarılı olmayan bir yönteme geçmek için bir yol bulmak zorunda. Bulmam gereken tek yol, delege olarak geçmek istediğim yöntemin adıyla bir dize geçirmek ve dizeyi yöntem içindeki bir temsilciye dönüştürmekti. Çok güzel bir cevap. Teşekkürler. Bu bağlantıyı kontrol edin https://msdn.microsoft.com/en-us/library/53cz7sc6(v=vs.110).aspx


0
Bu kod konsolumda çalışıyor. Net uygulaması
class Program
{
    static void Main(string[] args)
    {
        string method = args[0]; // get name method
        CallMethod(method);
    }
    
    public static void CallMethod(string method)
    {
        try
        {
            Type type = typeof(Program);
            MethodInfo methodInfo = type.GetMethod(method);
            methodInfo.Invoke(method, null);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            Console.ReadKey();
        }
    }
    
    public static void Hello()
    {
        string a = "hello world!";
        Console.WriteLine(a);
        Console.ReadKey();
    }
}

SO hoş geldiniz! Cevabınızı seviyorum, ne yaptığınız hakkında biraz daha açıklayabilir misiniz?
a.deshpande012

Merhaba, ders dışı.Bu bir konsol .net uygulaması, "program sınıfı" içinde çeşitli yöntemler veya işlevler vardır, örneğin: merhaba, merhaba2, merhaba2. "CallMethod (string method)" yöntemi arama ve dize parametresi olarak adlandırdığı "program sınıfı" içindeki herhangi bir yöntemi çağırmama izin verin. Uygulamayı "Windows Konsolu" ndan çalıştırdığımda: "name app" + "yöntemini çağırmam gerekiyor" yazıyorum. Örneğin: myapp merhaba, sonra "merhaba dünya!" Ayrıca "myapp hello2" veya "myapp hello3" olabilir. Herhangi bir .Net uygulamasında çalışabileceğini düşünüyorum.
ranobe

Reflection sınıfını eklemeniz gerekir: "using System.Reflection;".
ranobe

-9

C # 'da, işlev işaretçileri olarak delegeler oluşturabilirsiniz. Kullanım hakkında bilgi için aşağıdaki MSDN makalesine bakın:http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx

    public static void hello()
    {
        Console.Write("hello world");
    }

   /* code snipped */

    public delegate void functionPointer();

    functionPointer foo = hello;
    foo();  // Writes hello world to the console.

15
bu iplerden değil!
nawfal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.