2014-02-28 167 views
1

我有这个塞纳里奥我需要提供JSON反序列化类型的类型,我该怎么做它的动态?在运行时创建的类型参数的泛型类型

在这里,代码使用的示例类名(rd.ds.SDK.re.sa),但在现实的代码类型将使用来自数据库中的数据来构造。

Type dynamicalyCreatedAtRuntime = Type.GetType("rd.ds.SDK.re.sa"); 

var response = webRequest.ReadJsonResponseAs<Result<AnalysisResult<dynamicalyCreatedAtRuntime>>(); 


public static T ReadJsonResponseAs<T>(this HttpWebRequest webRequest) 
{ 
    using (System.IO.Stream responseStream = webRequest.GetResponse().GetResponseStream()) 
    { 
     using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream)) 
     { 
      T result = JsonConvert.DeserializeObject<T>(sr.ReadToEnd()); 

      responseStream.Close(); 
      return result; 
     }      
    } 
} 
+0

可能重复: //stackoverflow.com/questions/1151464/how-to-dynamically-create-generic-c-sharp-object-using-reflection) – Yuriy

+0

是'ReadJsonResponseAs'的扩展方法?是在第三方库中定义的吗?检查API是否暴露了一个带有'Type'对象而不是泛型类型参数的重载。 – dcastro

+3

不是重复的。这是调用一个通用的方法。 –

回答

2

使用JsonConvert.DeserializeObject代替this overload

public static object ReadJsonResponseAs(this HttpWebRequest webRequest, Type type) 
{ 
    using (System.IO.Stream responseStream = webRequest.GetResponse().GetResponseStream()) 
    { 
     using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream)) 
     { 
      object result = JsonConvert.DeserializeObject(sr.ReadToEnd(), type); 

      responseStream.Close(); 
      return result; 
     }      
    } 
} 

很显然,你需要把结果作为object。由于在编译期间你不知道对象的类型,因此使用泛型或使用反射来调用泛型重载没有意义。


您还应该创建这些类型的非通用版本:Result<T>AnalysisResult<T>

必须动态创建类型,例如Result<AnalysisResult<dynamicalyCreatedAtRuntime>>在运行时可能可以用反射来完成,但这样做会有0个好处。这尖叫重新设计。

+0

我不知道我知道我该如何使结果和AnalysisResult 非通用并利用它们来提供一个类型。 – user3357776

+0

@ user3357776是“结果”您创建的类型? – dcastro

+0

是的,所有这些都是我的类型 – user3357776

0

如果可以的话,我会用Netwonsoft.JSON(Json.Net)这一点。

var json = ...get request body... 
var type = Type.GetType("a.b.c"); 
var obj = JsonConvert.DeserializeObject(json, type); 

在Json.NET中也有很多帮助。如果您不控制类,这可能不起作用,并且需要自定义转换。

如果你绝对必须调用泛型方法,您将需要使用反射来手动构建呼叫。这变得棘手,可能不值得。

var m = webRequest.GetType().GetMethod("ReadJsonResponseAs"); 
var func = m.MakeGenericMethod(type); 
func.Invoke(webRequest, null); /* invoke func on webRequest object, no params */ 

您的泛型是深度嵌套的吗?如果是这样,你可能不得不分别制作每个关卡。

0

使用反射来获取下手,然后用MakeGenericMethod提供类型参数“构建”它的方法:

Type dynamicalyCreatedAtRuntime = Type.GetType("rd.ds.SDK.re.sa"); 
MethodInfo method = webRequest.GetType().GetMethod("ReadJsonResponseAs"); 
MethodInfo generic = method.MakeGenericMethod(dynamicalyCreatedAtRuntime); 
generic.Invoke(this, null); 
[如何使用反射动态创建通用的C#对象?(HTTP的