如何在C#中实现按名称调用?

发布于 2024-09-29 00:24:18 字数 60 浏览 1 评论 0原文

谁能告诉我如何在C#中实现按名称调用

Can anyone tell me how I can implement Call By Name in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

自此以后,行同陌路 2024-10-06 00:24:18

传递 lambda 函数而不是值。 C# 是急切评估的,因此为了推迟执行,以便每个站点重新评估提供的参数,您需要将参数包装在函数中。

int blah = 1;

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

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

Foo(() => blah * 100);

如果您使用 .NET 4.0,则可以使用 Lazy 类获得类似(但不相同)的效果。 Lazy 会记住结果,以便重复访问时不必重新评估函数。

Pass a lambda function instead of a value. C# is eagerly evaluated so in order to defer execution so that each site re-evaluates the supplied arguments you need to wrap the arguments in a function.

int blah = 1;

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

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

Foo(() => blah * 100);

You can use the Lazy class if you're in .NET 4.0 to get a similar (but not identical) effect. Lazy memoizes the result so that repeated accesses do not have to re-evaluate the function.

柒夜笙歌凉 2024-10-06 00:24:18
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;
}
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;
}
墨落成白 2024-10-06 00:24:18

您可以使用反射来做到这一点:

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);
   }
}

You can do that using 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);
   }
}
面犯桃花 2024-10-06 00:24:18

如果您的意思是这个,那么我认为最接近的等价物是代表。

If you mean this, then I think the closest equivalent would be delegates.

好久不见√ 2024-10-06 00:24:18

为什么不使用

Microsoft.VisualBasic.Interaction.CallByName

Why not use

Microsoft.VisualBasic.Interaction.CallByName
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文