2010-10-25 2 views
5

Quelqu'un peut-il me dire comment je peux mettre en œuvre Appelez par le nom dans C#?Comment implémenter l'appel par nom en C#?

+0

Quelle version de C# vous utilisez (ce qui est votre version de Visual Studio)? –

+0

Un compilateur en C#, qui en aurait eu! –

+0

@ 0xA3: Cela n'a pas d'importance, ça devrait être comme un compilateur ou quelque chose comme ça ... –

Répondre

2

Vous pouvez le faire en utilisant 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

Ce n'est pas un appel par son nom. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name –

+5

L'OP fait probablement référence à http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name, ce qui est différent de l'appel dynamique d'une méthode basée sur le nom. –

+0

Étant donné qu'ils ont accepté cette réponse, je soupçonne que l'OP faisait référence aux délégués [CallByName] de VB.NET (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.callbyname) – isedwards

1

Si vous voulez dire this, alors je pense que le plus proche équivalent serait délégués.

+0

délégués? peux-tu expliquer comment ?! voulez-vous dire, juste en utilisant un délégué? –

+0

L'exemple de Ron Warholic est un exemple de délégué. –

9

Passez une fonction lambda au lieu d'une valeur. C# est vivement évalué afin de différer l'exécution de sorte que chaque site réévalue les arguments fournis dont vous avez besoin pour envelopper les arguments dans une fonction.

int blah = 1; 

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

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

Foo(() => blah * 100); 

Vous pouvez utiliser la classe Lazy si vous êtes dans .NET 4.0 pour obtenir un effet similaire (mais pas identique). Lazy mémoizes le résultat afin que les accès répétés ne doivent pas réévaluer la fonction.

+3

Pour ceux qui se demandent, en utilisant 'Lazy ' se traduira par * appel par besoin *. – porges

+0

Une fonction lambda est une façon de générer un 'délégué '. –

+2

@Steven: En effet, cependant, strictement parlant, les lambdas ne sont pas des délégués mais implicitement convertibles en types de délégués correspondants. –

0

Pourquoi ne pas utiliser

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; 
} 
Questions connexes