简体   繁体   English

如何根据实际运行时类型动态调用方法?

[英]How do I invoke methods dynamically based on the actual runtime type?

I am receiving JSON from an outside source (with type info in it) that I deserialize with JSON.NET 我从外部源(其中包含类型信息)接收JSON,我使用JSON.NET反序列化

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.TypeNameHandling = TypeNameHandling.All;
//because the type info is included 'obj' will be of type Foo, Bar, Baz, etc
var obj = JsonConvert.DeserializeObject(jsonString, settings); 

I also receive the type of command that I need to execute on the object (eg Send, Retrieve, Remove, etc). 我还收到了我需要在对象上执行的命令类型(例如Send,Retrieve,Remove等)。 I use this to invoke the correct method on a service. 我用它来调用服务上的正确方法。 The service defines its methods for each type in this format (note: I don't maintain the service, I just call it): 该服务以这种格式为每种类型定义其方法(注意:我不维护服务,我只是称之为):

///where T has an implementation for each type (Foo, Bar, etc)
T Send(T objToSend)
T Retrieve (T objToRet)
T Remove (T objToRemove)

so for example: 例如:

Foo f = service.Send(aFoo);
Bar b = service.Send(aBar);
Foo f2 = service.Retrieve(aFoo);
Bar b2 = service.Retrieve(aBar);

is there a more elegant way to do this other than a big switch statement and if-else blocks for every type? 除了一个大的switch语句和if-else块之外,还有更优雅的方法吗? This will work, but it seems really clunky and if we continue to add types it will only get clunkier 这样可行,但看起来真的很笨重,如果我们继续添加类型,它只会变得笨拙

switch(command){
    case "Send":
        if(obj is Foo){
            service.Send((Foo)obj);
        }
        if(obj is Bar){
            service.Send((Bar)obj);
        }
        if(obj is Baz){
            service.Send((Baz)obj);
        }
    break;
    case "Retrieve":
    //etc...
    case "Remove":
    //etc...
}

thank you for any insight you can provide 感谢您提供的任何见解

You could use relfection to achieve this. 您可以使用relfection来实现此目的。 Given the following classes: 鉴于以下类别:

public class Bar
{
}

public class Foo
{
}

public class Service
{
    public Bar Send(Bar objToSend)
    {
        Console.WriteLine("Send Bar");
        return objToSend;
    }

    public Foo Send(Foo objToSend)
    {
        Console.WriteLine("Send Foo");
        return objToSend;
    }
}

Call the service in the following way: 以下列方式呼叫服务:

// This is the object we received and need to process
var obj = new Bar();

// This is the method we need to execute
string method = "Send";

// Initialize a new service and get its type
var service = new Service();
Type serviceType = service.GetType();

// Get the correct method by looking at the method name and the parameter type
MethodInfo methodInfo = serviceType.GetMethods().FirstOrDefault(x => x.Name == method && x.GetParameters()[0].ParameterType == obj.GetType());

// Invoke the method
object returnObj = methodInfo.Invoke(service, new object[] { obj });

If you care about performance at all, I recommend against this approach, and simply use a switch instead. 如果您完全关心性能,我建议不要使用这种方法,而只需使用开关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 NUnit 根据来自外部文件的值在运行时动态运行测试方法? - How can I run test methods dynamically on runtime based on values from external file with NUnit? 如果泛型类型参数在运行时之前是未知的,如何调用静态泛型类方法? - How to invoke static generic class methods if the generic type parameters are unknown until runtime? 如何根据属性的运行时类型动态选择验证器? - How to dynamically select a validator based on property's runtime type? 如何调用具有动态确定的类型参数的泛型方法? - How could I invoke a generic method with dynamically determined type parameters? 如何在运行时将方法附加到动态创建的C#类型? - How do I attach a method to a dynamically-created C# type at runtime? 如何与Parallel.Invoke并行启动方法? - How do I start methods in parallel with Parallel.Invoke? Roslyn,如何在运行时在脚本中实例化一个类并调用该类的方法? - Roslyn, how can I instantiate a class in a script during runtime and invoke methods of that class? 如何动态调用接收回调作为参数的dll方法? - How do i dynamically invoke a dll method that receives a callback as parameter? 如何在运行时“调用”类型为 Action&lt;,&gt; 的 PropertyInfo - How to "invoke" PropertyInfo of type Action<,> in runtime 如何基于C#&lt;4中的参数运行时类型调度方法? - How do I dispatch to a method based on a parameter's runtime type in C# < 4?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM