C# 动态执行函数的名称?

标签 c# .net dynamic .net-4.0

我有一个动态变量

动态 d = GetSomeObject();

在未来的某个时候,用户会向我发送一个要执行的函数(其名称),例如"UsersGetAll"

所以我需要做类似的事情:d.UsersGetAll()

我可以通过反射(reflection)来做到这一点。但我想使用 DLR。

这样做的唯一解决方案是让 MyObject 继承 DynamicObject 然后实现 TryInvokeMember 吗?

如果我无法控制类(class)怎么办?

最佳答案

正如 Jon 所说,以下内容仅在您怀疑类型在运行时通过 DLR 提供方法时才适用;在大多数简单的情况下,反射会更容易。

dynamic 适用于您知道方法名称但不知道目标的情况。如果您不知道方法名称,那就更麻烦了。也许棘手的一点是确保您保留调用站点以便可以重新使用它(这就是 DLR 保持性能的方式)。一种厚颜无耻的方法是使用静态实用程序类来跟踪调用的方法。这是一个示例 - 请注意,如果您需要处理参数,它会变得很多更困惑:

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Runtime.CompilerServices;
public class Foo
{
    public object Bar() { return "I was here"; }
}
static class Program
{
    static void Main()
    {
        object obj = new Foo();
        object result = DynamicCallWrapper.Invoke(obj, "Bar");
        Console.WriteLine(result);
    }
}

static class DynamicCallWrapper
{
    // Hashtable has nice threading semantics
    private static readonly Hashtable cache = new Hashtable();
    public static object Invoke(object target, string methodName)
    {
        object found = cache[methodName];
        if (found == null)
        {
            lock (cache)
            {
                found = cache[methodName];
                if(found == null)
                {
                    cache[methodName] = found = CreateCallSite(methodName);
                }
            }
        }
        var callsite = (CallSite<Func<CallSite, object,object>>)found;
        return callsite.Target(callsite, target);
    }
    static object CreateCallSite(string methodName)
    {
        return CallSite<Func<CallSite, object, object>>.Create(
            Binder.InvokeMember(
            CSharpBinderFlags.None, methodName, null, typeof(object),
            new CSharpArgumentInfo[] {
                CSharpArgumentInfo.Create(
                     CSharpArgumentInfoFlags.None, null) }));

    }
}

关于C# 动态执行函数的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13606522/

相关文章:

c# - 获取名称以特定字符串开头的所有控件

c# - .NET DateTime Parse 抛出异常

c# - 你如何处理大于 UInt64 的数字 (C#)

c# - 我的(巨大的)应用程序抛出了 OutOfMemoryException,现在怎么办?

C++ 在调整大小的动态数组中填充新元素

c# - 关闭时发送到托盘

C#引用分配未按预期工作

c# - .net framework 内置的抽象类都有哪些?

javascript - 使用带有添加和删除元素条件的 jQuery 克隆表单

c++ - 删除动态数组c++时出错