2010-10-25 19 views
5

¿Alguien puede decirme cómo puedo implementar Llamar por nombre en C#?¿Cómo implementar una llamada por nombre en C#?

+0

¿Qué versión de C# está usando (lo que es la versión de Visual Studio)? –

+0

Un compilador en C#, ¿quién lo hubiera probado? –

+0

@ 0xA3: No importa, debería ser como un compilador o algo así ... –

Respuesta

2

Usted puede hacer que el uso de Reflection:

 
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

Esto no es por llamada. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name –

+5

El OP probablemente se refiere a http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name, que es diferente de llamar dinámicamente a un método basado en el nombre. –

+0

Dado que aceptaron esta respuesta, sospecho que OP se estaba refiriendo a los delegados de [CallByName] de VB.NET (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.callbyname) – isedwards

1

Si se refiere a this, entonces creo que el equivalente más cercano sería delegados.

+0

? ¿Puedes explicar cómo? ¿quieres decir, simplemente usando un delegado? –

+0

El ejemplo de Ron Warholic es un ejemplo de un delegado. –

9

Pase una función lambda en lugar de un valor. C# se evalúa con entusiasmo, por lo que para diferir la ejecución de modo que cada sitio vuelva a evaluar los argumentos proporcionados, debe envolver los argumentos en una función.

int blah = 1; 

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

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

Foo(() => blah * 100); 

Usted puede utilizar la clase Lazy si estás en .NET 4.0 para obtener un efecto similar (pero no idéntico). Lazy memoriza el resultado para que los accesos repetidos no tengan que volver a evaluar la función.

+3

Para aquellos que se preguntan, usar 'Lazy ' dará como resultado * call-by-need *. – porges

+0

Una función lambda es una forma de generar un 'delegado'. –

+2

@Steven: De hecho, sin embargo, en términos estrictos, las lambdas no son delegadas, sino implícitamente convertibles en tipos de delegados coincidentes. –

0

Por qué no usar

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; 
} 
Cuestiones relacionadas