【问题标题】:How to implement call by name in C#?如何在 C# 中实现按名称调用?
【发布时间】:2010-10-25 21:57:31
【问题描述】:

谁能告诉我如何在 C# 中实现 Call By Name

【问题讨论】:

  • 你使用的是什么版本的 C#(你的 Visual Studio 版本是什么)?
  • C# 中的编译器,谁知道呢!
  • @0xA3:没关系,应该是编译器之类的吧……
  • @Dr TJ:当您询问实现时,这有什么关系?不同版本的 C# 有不同的可用功能。
  • @Dr TJ:是的,而且 C# 4.0 是一种不同于 C# 2.0 的编程语言,具有不同的改进功能来精确处理这个问题。

标签: c# compiler-theory callbyname


【解决方案1】:

传递一个 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 会记住结果,这样重复访问就不必重新评估函数。

【讨论】:

  • 对于那些想知道的人,使用Lazy&lt;T&gt; 将导致按需调用
  • lambda 函数是生成delegate 的一种方法。
  • @Steven:确实,但是严格来说 lambda 不是委托,而是隐式转换为匹配的委托类型。
  • 如果我们将其作为表达式树进行操作,这种区别会很重要,但在这里不会有任何区别。
【解决方案2】:

您可以使用Reflection

使用系统; 使用 System.Reflection; 类 CallMethodByName { 字符串名称; CallMethodByName(字符串名称) { this.name = 名称; } public void DisplayName() // 按名称调用的方法 { Console.WriteLine(名称); // 证明我们调用了它 } 静态无效主要() { // 实例化这个类 CallMethodByName cmbn = new CallMethodByName ("CSO"); // 通过名称获取所需的方法:DisplayName 方法信息方法信息 = typeof (CallMethodByName).GetMethod ("DisplayName"); // 使用实例调用不带参数的方法 methodInfo.Invoke (cmbn, null); } }

【讨论】:

【解决方案3】:
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;
}

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 代表?你能解释一下吗?!你的意思是,只使用一个委托?
    • Ron Warholic 的例子是代表的例子。
    【解决方案5】:

    为什么不使用

    Microsoft.VisualBasic.Interaction.CallByName
    

    【讨论】:

      猜你喜欢
      • 2016-09-08
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 2015-06-07
      • 2018-02-25
      • 2012-02-20
      相关资源
      最近更新 更多