关于动态调用方法并返回相应类型的建议

时间:2016-07-10 18:08:28

标签: c# generics dynamic reflection runtime

我有许多DataObject都继承自特定的类,并且这些DataObject每个都有类似的API调用方法。我正在尝试编写一个抽象方法,允许我接受API路径和请求方法类型的输入(" Get"," Put","发布"等)以进行适当的API调用,并返回该类型的对象。

注意:因为我将进行API调用,所以我需要确保async / await是可能的。

这是描述我想要做的非工作代码:

var dict = Dictionary<Tuple<string, string>, Action>>
{
    //many key/value pairs of RequestMethodType/APIPath tuple keys 
    //and API calling method values
};

public T APICaller<T>(string requestMethodType, string path)
{
    //make tuple of rmt and path
    //use tuple to get API calling Action value from dictionary
    //invoke method and return object of correct type
}

过去几天我做了很多搜索,以下是我正在尝试/考虑的一些选项:

  1. 使用词典,动作&gt;将输入映射到方法。 -issue with void lambda,努力恢复正确的类型

  2. 使用C#Generics调用API并返回正确的DataObject - 我无法返回动态类型的问题

  3. 使用反射制作通用方法以尝试解决#2

  4. 使用dyanmic关键字允许在运行时确定类型

  5. *我还尝试将RequestMethodType / Path元组映射到返回类型,然后使用返回类型作为进行API调用的泛型方法的返回类型。在尝试这个时,我无法通过一个错误,说我在预期类型时使用变量。 (用反射解决??)

    以下是我读过的类似问题的一些链接:

    C# Is it possible to pass a type into a method and have the method return an object of that type?

    How do I use reflection to call a generic method?

    generic class, how to set the type in runtime? - 以及更多,更多。

    编辑(添加我一直在处理的代码):

    using System;
    using System.Collections.Generic;
    
    namespace GenericsTest2
    {
        class MainClass
        {
    
            public static Dictionary<Tuple<string, string>, Type> dict  = new Dictionary<Tuple<string, string>, Type>()
            {
                {new Tuple<string, string> ("Get", "/path/to/api"), typeof(Car)}
            };
    
            public static void Main (string[] args)
            {
                string requestType = "Get";
                string path = "user/path";
                var objType = DetermineType (requestType, path);
                var obj = (Car)(object)GetObject (objType, path);
                Console.WriteLine (obj.Name);
            }
    
            public static Car CarMethod()
            {
                return new Car {Name = "John"};
            }
            public static Truck TruckMethod()
            {
                return new Truck {Id  = "ABC123"};
            }
    
            public static Type DetermineType(string requestMethodType, string path)
            {
                var tuple = Tuple.Create (requestMethodType, path);
                Type myData;
                dict.TryGetValue (tuple, out myData);
                return myData;
            }
    
            public static DataObject GetObject(Type t, string path)
            {
                //here I could use the path to call the actual API, but I'll just call 
                //CarMethod or TruckMethod to generate data for testing
                if(path == "user/path"){
                    return CarMethod ();
                }else if (path == "settings/path"){
                    return TruckMethod();
                }else{
                     throw new Exception ("something went wrong!");
                }
            }
    
            public class DataObject
            {
                public string Api { get; set; }
            }
    
            public class Car : DataObject
            {
                public string Name { get; set; }
            }
    
            public class Truck : DataObject
            {
                public string Id { get; set; }
            }
        }
    }
    

0 个答案:

没有答案