我编写了下面的代码,将字典转换为json字符串。 这里的问题是字典值可以是各种类型 string,int,string [],int [],float [],... 我尝试使用泛型,但是我得到一个编译错误,我在其中执行GetParamList,因为它希望我指定实际类型。 我想知道是否有办法可以避免使用大量的if / else条件来实现我想要的目标。
private static string GetParamList<T>(object values)
{
if (values.GetType().Equals(typeof(string[])) )
{
string[] res = (string[])values;
if (values.GetType().Equals(typeof(string[])))
{
for (int i = 0; i < res.Length; i++)
{
if (!res[i].ToString().StartsWith("\""))
{
res[i] = string.Format("\"{0}\"", res[i]);
}
}
}
return string.Join(",", res);
}
else if (values.GetType().Equals(typeof(string)))
{
return string.Format("\"{0}\"", values);
}
else// array of numbers:
{
string[] res = ((T[])values).Select(x => x.ToString()).ToArray<string>();
return string.Join(",", res);
}
}
private static string dictToJson(Dictionary<string, object> data)
{
List<string> entries = new List<string>();
foreach (var entry in data)
{
Type T = entry.Value.GetType();
entries.Add(string.Format("\"{0}\": {1}", entry.Key, GetParamList<T>(entry.Value)));
}
return "{" + string.Join(",", entries.ToArray<string>()) + "}";
}
答案 0 :(得分:1)
这里犯了错误:
Type T = entry.Value.GetType();
您在此处所做的是不获取通用参数 - 相反,您将获得表示所需参数的类Type
的对象。泛型设计用于在编译时使用已知类型,因此JIT编译器可以为您动态创建类的定义。因此,您无法将Type
对象作为通用参数传递。
然而,有几种方法可以解决这个问题。
第一个也是最简单的方法是使用可以执行通用推理的工厂方法,并将通用参数作为dynamic
传递。这将强制CLR延迟到运行时以决定使用哪种类型,然后使用最匹配的类型作为参数。并非不按原样使用您的代码 - 泛型推理要求您使用T
作为参数类型以及泛型类型,例如:
private static string GetParamList<T>(T[] values)
第二种方法是对操作进行元代码并使用System.Linq.Expressions
命名空间编译调用,这可能会更加详细:
var val = Expression.Constant(entry.Value);
var method = typeof(MyType) // Where MyType is the type containing "GetParamList"
.GetMethod("GetParamList")
.MakeGenericMethod(t); // Where t is the desired type
string result = Expression
// Lambda turns an expression tree into an expressiong tree with an explicit delegate signature
.Lambda<Func<String>>(
Expression.Call(null, method, val)) // "Call the method against nothing (it's static) and pass in val (which is a constant in this case)"
.Compile() // This compiles our expression tree
.Invoke(); // Run the method
答案 1 :(得分:0)
你正在努力学习,试试这个。
public List<Event_Log> GetAll()
{
List<Event_Log> result = new List<Event_Log>();
//add result collection here...
return result;
}
答案 2 :(得分:0)
感谢您推荐&#34; Newtonsoft.Json&#34;。 我以这种方式使用了这个包,所有的问题都解决了:
private static string dictToJson(Dictionary<string, object> data)
{
string json = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
});
return json;
}