0

我有一个接收字符串的网络服务。

此字符串包含多个键 => 与字符“+”连接的值。

我必须验证每个值(“必需”、“非空”),并将每个值分配给具有相同名称的变量。

这是我从字符串构建字典的方法:

string firstname;
string lastname;
string amount;

string request = "firstname=foo+lastname=bar+amout=100.58";

Dictionary<string, string> arguments = new Dictionary<string, string>();

request.Split('+').ToList<string>().ForEach(p =>
{
    string[] tmp = p.Split('=');

    if (tmp.Length == 2)
        arguments.Add(tmp[0], tmp[1]);
});

// Validate and assign : How I do with one value : (I must find a better way)
bool isValid = true;

// check "firstname"
if(arguments.ContainsKey("firstname") && string.IsNullOrWhiteSpace(arguments["firstname"]) == false)
{
    firstname = arguments["firstname"];
}
else
{
    isValid = false;
    Logger.Write("Invalid argument : firstname");
}

// Do this for about 20 arguments, it becomes huge...

if(isValid)
{
    Console.WriteLine(firstname); // Displays foo
    Console.WriteLine(lastname); // Displays bar
    Console.WriteLine(amout); // Displays 100.58
}

谢谢,抱歉拼写错误,我是法国人。

4

3 回答 3

0

认为您想要这样的东西,但是由于您没有真正提出问题,所以我只是在猜测:

request.Split('+').ToList<string>().ForEach(p =>
{
    string[] tmp = p.Split('=');

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1]))
    {
        // edit - if your string can have duplicates, use
        // Dictionary<U,K>.ContainsKey(U) to check before adding
        var key = tmp[0];
        var value = tmp[1];

        if(!arguments.ContainsKey(key))
        {
            arguments.Add(key, value);
        }
        else
        {
            //overwrite with new value
            //could also maybe throw on duplicate or some other behavior.
            arguents[key]=value; 
        }
    }
    else
        throw InvalidOperationException("Bad dictionary string value");
});

另外,如果在代码审查中出现在我面前,我会质疑 ToList->ForEach 的使用。您想避免 Linq 中的副作用,我会使用传统的 foreach 来编写它,例如:

var itemValues = request.Split('+');
foreach(var item in itemValues)
{
    string[] tmp = item.Split('=');

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1]))
        arguments.Add(tmp[0], tmp[1]);
    else
        throw InvalidOperationException("Bad dictionary string value");
});



// Validate and assign
//read values from the dictionary
//use ContainsKey to check for exist first if needed

Console.WriteLine(arguments["firstname"]); // Displays foo
Console.WriteLine(arguments["lastname"]); // Displays foo
Console.WriteLine(arguments["amout"]); // Displays 100.58

编辑 2 - 您应该将逻辑封装在一个方法中:

private string TryGetValue(IDictionary<string,string> dict,string key)
{
    string value = null;
    if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key]))
    {
        value = dict[key];
    }
    else
    {
        Logger.Write("Invalid argument : " + key);
    }
    return value;
}

现在你可以说:

string firstName = TryGetValue(arguments,"firstname");
string lastName= TryGetValue(arguments,"lastName");
string amount = TryGetValue(arguments,"amount");

bool isValid = firstName!=null && lastName != null && amount != null;

if(isValid)
{
    Console.WriteLine(firstName ); // Displays foo
    Console.WriteLine(lastName); // Displays bar
    Console.WriteLine(amout); // Displays 100.58
}

TryGetValue将成为一个很好的扩展方法:

public static class Extensions
{
    public static string TryGetValue(this IDictionary<string,string> dict, string key)
    {
        string value = null;
        if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key]))
        {
            value = dict[key];
        }
        else
        {
            Logger.Write("Invalid argument : " + key);
        }
        return value;
    }

}

现在调用代码如下所示:

string firstName = arguments.TryGetValue("firstname");
string lastName= arguments.TryGetValue("lastname");
string amount = arguments.TryGetValue("amount");

最后一次编辑 - 关于扩展方法的注释 - 是的,它们很整洁,但也很容易意外地过度使用它们。阅读有关它们的 msdn 和博客,遵循指南。避免对泛型类型进行扩展,例如object,等string

在我的项目中,我总是根据与之交互的类型在不同的命名空间中布置扩展方法,这迫使希望使用它们的类非常明确,例如:

namespace Extensions.IDictionary { ... }
namespace Extensions.string { ... }
namespace Extensions.SomeType { ... }
namespace Extensions.IList { ... }

并且使用代码将具有using匹配的子句:

using Extensions.IDictionary;

仅提取您感兴趣的扩展,仅此而已。

于 2012-04-19T14:38:40.733 回答
0

这只是一个猜测,因为您的问题不清楚。

// Validate and assign

foreach(KeyValuePair<string,string> pair in arguments)
{
    if(!String.IsNullOrEmpty(pair.Value))
    {
        Console.WriteLine(pair.Value);
    }
}
于 2012-04-19T14:40:54.357 回答
0

如果您有多个名字和姓氏,并且您可以使用列表作为字典的值。这样,您可以简单地为名字、姓氏和其他人添加其他值。

要验证,您可以在将值添加到字典之间进行:

 string request = "firstname=foo+lastname=bar+amout=100.58+firstname=+lastname=bar2+amout=100.59+firstname=foo3+lastname3=bar3+amout=100.60";

        Dictionary<string, List<string>> arguments = new Dictionary<string, List<string>>();
        request.Split('+').ToList<string>().ForEach(f =>
            {
                string[] data = f.Split('=');
                if (data.Length == 2)
                {
                    if (!arguments.ContainsKey(data[0]))
                    {
                        if (data[1] != "")
                            arguments.Add(data[0], new List<string> { data[1] });
                        else
                            arguments.Add(data[0], new List<string> { "no firstname" });
                    }
                    else
                    {
                        if (data[1] != "")
                            arguments[data[0]].Add(data[1]);
                        else
                            arguments[data[0]].Add("no firstname");
                    }
                }
            });

希望对你有帮助,再见

于 2012-04-19T14:57:30.873 回答