将匿名对象的属性和值转换为字典
问题描述:
我正在为现有API创建一个库。我目前有每个请求类的QueryParameter类。 QueryParameter类很简单,但它们有所不同(不是所有的请求都采用相同的查询参数)。将匿名对象的属性和值转换为字典
这里是一个QueryParameter类的例子:
public class ApiRequestAQueryParameters
{
public string Name { get; set; }
public int Start { get; set; }
public int Stop { get; set; }
}
我感兴趣的方式来这样的类转换成一个字典,我可以养活我们的Web客户端。我希望能有这样一个可重复使用的方法:
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
// perform conversion
}
这样我就不必拔出QueryParameter性质为每个请求(会有几十请求)
,我的理由使用QueryParameter类而不是使QueryParameter成为每个API请求类的Dictionary属性是开发者友好的。我想要让其他人可以通过查看这些类来构建这些API请求。
答
有2种方法:1)使用反射和2)序列化到JSON和回。
这里是第一个方法:
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
var res = new Dictionary<string, string>();
var props = queryParametersObject.GetType().GetProperties();
foreach (var prop in props)
{
res[prop.Name] = prop.GetValue(queryParametersObject).ToString();
}
return res;
}
答
你可以做这样的事情:
private Dictionary<string, string> GenerateQueryParameters(object queryParameters)
{
var startStop = new StartStop() { Start = queryParameters.Start, Stop = queryParameters.Stop};
var result = new Dictionary<string, string>();
result.Add(queryParameters.Name, startStop);
return result;
}
public class StartStop
{
public int Start { get; set; }
public int Stop { get; set; }
}
答
这可能是利用ExpandoObjects完美的情况。 ExpandoObject是一个动态类型,其属性可以在运行时创建。 ExpandoObject实现IDictionary <字符串,对象>因此很容易将其转换为字典< string,object>。
在下面的示例中,将创建ExpandoObject并将其转换为字典< string,object>,然后转换为字典< string,string>。
dynamic apiVar = new ExpandoObject();
apiVar.Name = "Test";
apiVar.Start = 1;
apiVar.Stop = 2;
var iDict = (IDictionary<string, object>) apiVar;
/* if you can utilize a Dictionary<string, object> */
var objectDict = iDict.ToDictionary(i => i.Key, i => i.Value);
/* if you need a Dictionary<string, string> */
var stringDict = iDict.ToDictionary(i=>i.Key, i=> i.Value.ToString());
在ExpandoObject上设置属性的方法也不同。以下是通过变量名称设置属性的示例。
dynamic apiVar = new ExpandoObject();
var propertyName = "Name";
apiVar[propertyName] = "Test";
propertyName = "Start";
apiVar[propertyName] = 1;
propertyName = "Stop";
apiVar[propertyName] = 2;
答
我总是重复使用RouteValueDictionary类。它有一个接受任何对象的构造函数,而类本身实现了IDictionary。
这是在对System.Web DLL提供
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
return new RouteValueDictionary(queryParametersObject).ToDictionary(d => d.Key, d => Convert.ToString(d.Value));
}