简体   繁体   English

将匿名对象的属性和值转换为字典

[英]Converting an anonymous object's properties and values to a Dictionary

I am creating a library for an existing API.我正在为现有 API 创建一个库。 I currently have QueryParameter classes for each request class.我目前为每个请求类都有 QueryParameter 类。 The QueryParameter classes are simple but they do vary (not all requests take the same query parameters). QueryParameter 类很简单,但它们确实有所不同(并非所有请求都采用相同的查询参数)。

Here is an example of a QueryParameter class:下面是一个 QueryParameter 类的例子:

public class ApiRequestAQueryParameters
{
    public string Name { get; set; }
    public int Start { get; set; }
    public int Stop { get; set; }
}

I am interested in a way to convert a class like this into a Dictionary that I can feed to our Web client.我对将这样的类转换为可以提供给我们的 Web 客户端的字典的方法感兴趣。 I am hoping to have a reusable method like:我希望有一个可重用的方法,如:

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
// perform conversion
}

This way I won't have to pull out the QueryParameter properties for each request (there will be dozens of requests)这样我就不必为每个请求拉出 QueryParameter 属性(会有几十个请求)

The reason that I am using QueryParameter classes instead of making QueryParameter a Dictionary property of each API request class is to be developer friendly.我使用 QueryParameter 类而不是使 QueryParameter 成为每个 API 请求类的 Dictionary 属性的原因是为了对开发人员友好。 I want to make it so that others can build these API requests by looking at the classes.我想让其他人可以通过查看类来构建这些 API 请求。

There are 2 ways: 1) use reflection and 2) serialize to json and back.有两种方法:1) 使用反射和 2) 序列化到 json 并返回。

Here is the 1st method:这是第一种方法:

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;
}

You can do something like this:你可以这样做:

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; }
}

This may be the perfect case to utilize ExpandoObjects.这可能是使用 ExpandoObjects 的完美案例。 An ExpandoObject is a dynamic type, whose properties can be created at run time. ExpandoObject 是一种动态类型,其属性可以在运行时创建。 ExpandoObject implements IDictionary < string, object > so it's easy to convert to a Dictionary < string, object > . ExpandoObject 实现了 IDictionary < string, object > 因此很容易转换为 Dictionary < string, object > 。

In the example below, an ExpandoObject is created and converted to a Dictionary < string, object > and then converted to a Dictionary < string, string >.在下面的示例中,创建了一个 ExpandoObject 并将其转换为 Dictionary <string, object>,然后转换为 Dictionary <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());

There are also different ways of setting properties on an ExpandoObject.在 ExpandoObject 上设置属性也有不同的方法。 Below is an example of setting a property by a variable name.以下是通过变量名称设置属性的示例。

dynamic apiVar = new ExpandoObject();
var propertyName = "Name";
apiVar[propertyName] = "Test";
propertyName = "Start";
apiVar[propertyName] = 1;
propertyName = "Stop";
apiVar[propertyName] = 2;

I always reuse the RouteValueDictionary class for this.我总是为此重用RouteValueDictionary类。 It has a constructor that accepts any object and the class itself implements IDictionary.它有一个接受任何对象的构造函数,并且类本身实现了 IDictionary。

It's available in the System.Web dll它在 System.Web dll 中可用

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
    return new RouteValueDictionary(queryParametersObject).ToDictionary(d => d.Key, d => Convert.ToString(d.Value));
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM