Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以使用字符串方法名对c#动态调用方法吗?_C#_Dynamic_Signalr - Fatal编程技术网

我可以使用字符串方法名对c#动态调用方法吗?

我可以使用字符串方法名对c#动态调用方法吗?,c#,dynamic,signalr,C#,Dynamic,Signalr,我想知道是否可以通过字符串调用动态c#对象上的函数。我想这样做: string lMethodName = "MethodName"; dynamic lDynamicObject = GetDynamicObject(); lDynamicObject.Invoke(lMethodName, lParameters); class MyClass { public void Action() { Console.WriteLine("Do action"); } }

我想知道是否可以通过字符串调用动态c#对象上的函数。我想这样做:

string lMethodName = "MethodName";
dynamic lDynamicObject = GetDynamicObject();
lDynamicObject.Invoke(lMethodName, lParameters);
        class MyClass { public void Action() { Console.WriteLine("Do action"); } }
        // ...
        dynamic instance = new MyClass();
        instance.GetType().GetMethod("Action").Invoke(instance, null);
如有任何想法或解决方案,将不胜感激

也许正如Servy所说,有一种更好的方法可以通过不同的设计实现我们想要的。我们正在使用信号器,并有一个仪表板web应用程序。我们希望仪表板中的每个小部件都能够将数据推送到其中。为了实现这一点,我们将使用razor代码将小部件id注入每个单独的小部件SignalR客户端代理。每个小部件都有如下内容:

hub.client.updateWidget123456 = aUpdateFunction;
dynamic propertyBag = new PropertyBag();

propertyBag.Name = "stackoverflow";
propertyBag.Value = 42;
其中123456是小部件的id。在服务器端信号集线器代码中,我们可以调用客户端javascript函数:

int lWidgetId = 123456;
dynamic lDynamic = Clients.All;
lDynamic.Invoke("updateWidget" + lWidgetId, lParameters);
我可以想出其他方法来实现这一点,而无需创建javascript代理方法。我认为这很好,因为服务器与每个小部件都有直接的通信线路。可以从多个仪表板/浏览器访问,但它们都可以通过上面的单个调用进行更新

我们可以通过调用javascript客户端代码中的其他对象来实现这一点,这些对象了解所有小部件以及如何将信息定向到它们。我觉得这样做违背了信号机的枢纽架构,就像我们通过这样做来重塑车轮一样

有人对更好的设计方法有什么想法吗?谢谢你的帮助,谢谢你的评论,Servy引发了这次讨论


而且,这个问题不是重复的。另一个问题与Paul在下面评论的动态对象无关。

通过反射,我认为您可以这样做(如果是私有的->非公共的)


只需使用接受BindingFlags的GetMethod重载版本:

通过反射,我认为您可以这样做(如果它是private->NonPublic)


只需使用接受BindingFlags的GetMethod重载版本:

是,这是可能的。您想要做的就是所谓的“反射”,并且在大多数高级语言中都可以使用


下面是一个例子。它实际上非常强大,允许您在一定程度上让代码“意识到自己”

是的,这是可能的。您想要做的就是所谓的“反射”,并且在大多数高级语言中都可以使用


下面是一个例子。它实际上非常强大,可以让您的代码在一定程度上“自我意识”

简短回答,是的,您可以这样做:

string lMethodName = "MethodName";
dynamic lDynamicObject = GetDynamicObject();
lDynamicObject.Invoke(lMethodName, lParameters);
        class MyClass { public void Action() { Console.WriteLine("Do action"); } }
        // ...
        dynamic instance = new MyClass();
        instance.GetType().GetMethod("Action").Invoke(instance, null);
然而,在本例中,实例是动态类型这一事实完全不起任何作用。您可以使用
对象
类型,其工作方式相同。链中的第一个方法GetType()返回
typeof(MyClass)
,然后它就是从那里开始的简单的老式反射

使用dynamic关键字可以做到这一点,这更有趣,尽管在运行时灵活性稍差:

        dynamic instance = new MyClass();
        instance.Action();

这将在运行时使用反射查找操作。在本例中,
dynamic
的工作方式与
var
的工作方式并不明显,因为这里设置了
MyClass
,但是您可以使用第二行来执行任何名为action的方法,只要实例有一个同名的方法。

简短回答,是的,您可以这样做:

string lMethodName = "MethodName";
dynamic lDynamicObject = GetDynamicObject();
lDynamicObject.Invoke(lMethodName, lParameters);
        class MyClass { public void Action() { Console.WriteLine("Do action"); } }
        // ...
        dynamic instance = new MyClass();
        instance.GetType().GetMethod("Action").Invoke(instance, null);
然而,在本例中,实例是动态类型这一事实完全不起任何作用。您可以使用
对象
类型,其工作方式相同。链中的第一个方法GetType()返回
typeof(MyClass)
,然后它就是从那里开始的简单的老式反射

使用dynamic关键字可以做到这一点,这更有趣,尽管在运行时灵活性稍差:

        dynamic instance = new MyClass();
        instance.Action();

这将在运行时使用反射查找操作。在本例中,
dynamic
的工作方式与
var
不同并不明显,因为
MyClass
设置在这里,但您可以使用第二行来执行任何名为action的方法,只要实例有一个同名的方法。

如果您知道它是一个普通的C对象(即没有特殊的运行时绑定器),则只能使用反射来调用
动态
上的方法

考虑实现可动态使用的属性包的以下类:

public class PropertyBag : DynamicObject
{
    private Dictionary<string, object> _propertyBag = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _propertyBag.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _propertyBag[binder.Name] = value;
        return true;
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return base.GetDynamicMemberNames();
    }
}
但是,如果您尝试为这些动态属性中的任何一个获取
PropertyInfo
,它将失败,因为
PropertyBag
类没有实现它们:

public static void SetProperty(dynamic propertyBag, string propertyName, object value)
{
    PropertyInfo property = propertyBag.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
    if (property == null)
    {
        throw new NotImplementedException();
    }

    MethodInfo setProperty = property.GetSetMethod();
    setProperty.Invoke(propertyBag, new object[] { value });
}
这将引发异常:

dynamic propertyBag = new PropertyBag();

propertyBag.Name = "stackoverflow;      // works as expected
SetProperty(propertyBag, "Value", 42);  // throws a NotImplementedException
我在本例中使用了属性,因为它们更容易实现,但显然,同样的情况也适用于方法。这是因为
动态
是在运行时动态计算的,但反射只能反映在静态实现上。(在
PropertyBag
类上,哪些属性应该
GetProperties
返回?)


如果将
dynamic
用于普通C#对象,反射将按预期工作,但如果您不知道所处理的运行时绑定器的类型及其内部实现方式,则无法依赖反射。

如果您知道
dynamic
对象是普通C#对象,则只能使用反射来调用该对象上的方法对象(即没有特殊的运行时绑定器)

考虑实现可动态使用的属性包的以下类:

public class PropertyBag : DynamicObject
{
    private Dictionary<string, object> _propertyBag = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _propertyBag.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _propertyBag[binder.Name] = value;
        return true;
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return base.GetDynamicMemberNames();
    }
}
但是,如果您尝试为这些动态属性中的任何一个获取
PropertyInfo
,它将失败,因为
PropertyBag
类没有实现它们:

public static void SetProperty(dynamic propertyBag, string propertyName, object value)
{
    PropertyInfo property = propertyBag.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
    if (property == null)
    {
        throw new NotImplementedException();
    }

    MethodInfo setProperty = property.GetSetMethod();
    setProperty.Invoke(propertyBag, new object[] { value });
}
这将引发异常:

dynamic propertyBag = new PropertyBag();

propertyBag.Name = "stackoverflow;      // works as expected
SetProperty(propertyBag, "Value", 42);  // throws a NotImplementedException
我在本例中使用了属性,因为它们更容易实现,但显然,同样的情况也适用于方法。这样做的原因是
dynamic
是在运行时动态计算的,但反射只能反射