2010-10-25 16 views
5

Kann mir jemand sagen, wie ichAnruf nach Namen in C# umsetzen kann?Wie implementiert man Anruf nach Name in C#?

+0

Welche Version von C# verwenden Sie (was Sie Visual Studio-Version)? –

+0

Ein Compiler in C#, wer hätte das gedacht! –

+0

@ 0xA3: Es spielt keine Rolle, sollte es wie ein Compiler oder so ähnlich sein ... –

Antwort

2

Sie können das tun Reflection mit:

 
using System; 
using System.Reflection; 

class CallMethodByName 
{ 
    string name; 

    CallMethodByName (string name) 
    { 
     this.name = name; 
    } 

    public void DisplayName()  // method to call by name 
    { 
     Console.WriteLine (name); // prove we called it 
    } 

    static void Main() 
    { 
     // Instantiate this class 
     CallMethodByName cmbn = new CallMethodByName ("CSO"); 

     // Get the desired method by name: DisplayName 
     MethodInfo methodInfo = 
     typeof (CallMethodByName).GetMethod ("DisplayName"); 

     // Use the instance to call the method without arguments 
     methodInfo.Invoke (cmbn, null); 
    } 
} 
+5

Dies ist kein Call-by-Name. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name –

+5

Der OP bezieht am wahrscheinlich http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name die aus dynamisch Aufruf einer Methode, basierend auf dem Namen unterscheidet. –

+0

Da sie diese Antwort akzeptiert, vermute ich das OP tatsächlich zu VB.NET des bezog [CallByName] (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.callbyname) – isedwards

1

Wenn Sie this bedeuten, dann denke ich, die am ehesten vergleichbar Delegierten wären.

+0

Delegierten? kannst du erklären wie ?! meinst du, nur mit einem Delegierten? –

+0

Ron Warholics Beispiel ist ein Beispiel für einen Delegierten. –

9

Pass eine Lambda-Funktion anstelle eines Wertes. C# wird eifrig ausgewertet, um die Ausführung so zu verzögern, dass jede Site die übergebenen Argumente neu bewertet, die Sie benötigen, um die Argumente in eine Funktion zu packen.

int blah = 1; 

void Foo(Func<int> somethingToDo) { 
    int result1 = somethingToDo(); // result1 = 100 

    blah = 5; 
    int result2 = somethingToDo(); // result = 500 
} 

Foo(() => blah * 100); 

können Sie die Lazy Klasse verwenden, wenn Sie in .NET 4.0 sind ein ähnliches zu bekommen (aber nicht identisch) Wirkung. Lazy merkt das Ergebnis so, dass wiederholte Zugriffe die Funktion nicht neu bewerten müssen.

+3

Für diejenigen, die sich wundern, die Verwendung von 'Lazy ' führt zu * Call-by-Need *. – porges

+0

Eine Lambda-Funktion ist eine Möglichkeit, einen Delegierten zu generieren. –

+2

@Steven: In der Tat sind Lambdas streng genommen keine Delegaten, sondern implizit in übereinstimmende Delegattypen umwandelbar. –

0

Warum nicht

Microsoft.VisualBasic.Interaction.CallByName 
1
public enum CallType 
{ 
/// <summary> 
/// Gets a value from a property. 
/// </summary> 
Get, 
/// <summary> 
/// Sets a value into a property. 
/// </summary> 
Let, 
/// <summary> 
/// Invokes a method. 
/// </summary> 
Method, 
/// <summary> 
/// Sets a value into a property. 
/// </summary> 
Set 
} 

/// <summary> 
/// Allows late bound invocation of 
/// properties and methods. 
/// </summary> 
/// <param name="target">Object implementing the property or method.</param> 
/// <param name="methodName">Name of the property or method.</param> 
/// <param name="callType">Specifies how to invoke the property or method.</param> 
/// <param name="args">List of arguments to pass to the method.</param> 
/// <returns>The result of the property or method invocation.</returns> 
public static object CallByName(object target, string methodName, CallType callType, params object[] args) 
{ 
    switch (callType) 
    { 
    case CallType.Get: 
     { 
     PropertyInfo p = target.GetType().GetProperty(methodName); 
     return p.GetValue(target, args); 
     } 
    case CallType.Let: 
    case CallType.Set: 
     { 
     PropertyInfo p = target.GetType().GetProperty(methodName); 
     p.SetValue(target, args[0], null); 
     return null; 
     } 
    case CallType.Method: 
     { 
     MethodInfo m = target.GetType().GetMethod(methodName); 
     return m.Invoke(target, args); 
     } 
    } 
    return null; 
} 
Verwandte Themen