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

时间:2016-09-17 20:56:46

标签: c#

我正在为现有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请求。

4 个答案:

答案 0 :(得分:0)

有两种方法: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;
}

答案 1 :(得分:0)

您可以这样做:

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

答案 2 :(得分:0)

这可能是使用ExpandoObjects的最佳案例。 ExpandoObject是一种动态类型,其属性可以在运行时创建。 ExpandoObject实现IDictionary&lt; string,object&gt;所以很容易转换成字典&lt; string,object&gt;

在下面的示例中,创建了一个ExpandoObject并将其转换为Dictionary&lt; string,object&gt;然后转换为字典&lt; string,string&gt;。

import nltk
import pandas as pd

data = pd.read_csv("data.csv", sep=",")
#data.head()

datatext = data['Description']
#datatext.head()

import nltk
from nameparser import HumanName
#nltk.download()

def get_human_names(datatext):
    tokens = nltk.tokenize.word_tokenize(datatext.read())
    pos = nltk.pos_tag(tokens)
    sentt = nltk.ne_chunk(pos, binary = False)
    person_list = []
    person = []
    name = ""
    for subtree in sentt.subtrees(filter=lambda t: t.node == 'PERSON'):
        for leaf in subtree.leaves():
            person.append(leaf[0])
        if len(person) > 1: #avoid grabbing lone surnames
            for part in person:
                name += part + ' '
            if name[:-1] not in person_list:
                person_list.append(name[:-1])
            name = ''
        person = []

    return (person_list)

text = datatext

names = get_human_names(datatext)
print "LAST, FIRST"
for name in names: 
    last_first = HumanName(name).last + ', ' + HumanName(name).first
print last_first
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-18-2f6ec1c0b04c> in <module>()
     21 text = datatext
     22 
---> 23 names = get_human_names(datatext)
     24 print "LAST, FIRST"
     25 for name in names:

<ipython-input-18-2f6ec1c0b04c> in get_human_names(datatext)
      1 def get_human_names(datatext):
----> 2     tokens = nltk.tokenize.word_tokenize(datatext.read())
      3     pos = nltk.pos_tag(tokens)
      4     sentt = nltk.ne_chunk(pos, binary = False)
      5     person_list = []

C:\Anaconda2\lib\site-packages\pandas\core\generic.pyc in __getattr__(self, name)
   2358                 return self[name]
   2359             raise AttributeError("'%s' object has no attribute '%s'" %
-> 2360                                  (type(self).__name__, name))
   2361 
   2362     def __setattr__(self, name, value):

AttributeError: 'Series' object has no attribute 'read'

在ExpandoObject上设置属性的方法也有所不同。以下是通过变量名设置属性的示例。

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());

答案 3 :(得分:0)

我总是重复使用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));
}