C# 阅读字典<字符串、列表<String>>使用 LINQ 或 foreach 循环



我有一个字典对象如下:

private Dictionary<String, List<String>> errors =
        new Dictionary<string, List<string>>();

我已经实现了IDataErrorInfo在我的类Product . there是Dictionary<String, List<String>> errors在其中存储的错误验证属性(Id,Name)。如果我们把字典看作结构,那么TKey将是字符串,它将包含PropertyName和TValue错误列表的属性。下面是一个代码:

public class Product : IDataErrorInfo
{
    private int idValue;
    public int Id
    {
        get { return idValue; }
        set { if (IsIdValid(value) && idValue != value) idValue = value; }
    }
    private string nameValue;
    public string Name
    {
        get { return nameValue; }
        set { if (IsNameValid(value) && nameValue != value) nameValue = value; }
    }

    {
        bool isValid = true;
        if (value < 5)
        {
            AddError("Id", ID_ERROR, false);
            isValid = false;
        }
        else RemoveError("Id", ID_ERROR);
        if (value < 10) AddError("Id", ID_WARNING, true);
        else RemoveError("Id", ID_WARNING);
        return isValid;
    }

    public bool IsNameValid(string value)
    {
        bool isValid = true;
        if (value.Contains(" "))
        {
            AddError("Name", NAME_ERROR, false);
            isValid = false;
        }
        else RemoveError("Name", NAME_ERROR);
        if (value.Length > 5) AddError("Name", NAME_WARNING, true);
        else RemoveError("Name", NAME_WARNING);
        return isValid;
    }
    private Dictionary<String, List<String>> errors =
        new Dictionary<string, List<string>>();
    private const string ID_ERROR = "Value cannot be less than 5.";
    private const string ID_WARNING = "Value should not be less than 10.";
    private const string NAME_ERROR = "Value must not contain any spaces.";
    private const string NAME_WARNING = "Value should be 5 characters or less.";

    public void AddError(string propertyName, string error, bool isWarning)
    {
        if (!errors.ContainsKey(propertyName))
            errors[propertyName] = new List<string>();
        if (!errors[propertyName].Contains(error))
        {
            if (isWarning) errors[propertyName].Add(error);
            else errors[propertyName].Insert(0, error);
        }
    }

    public void RemoveError(string propertyName, string error)
    {
        if (errors.ContainsKey(propertyName) &&
            errors[propertyName].Contains(error))
        {
            errors[propertyName].Remove(error);
            if (errors[propertyName].Count == 0) errors.Remove(propertyName);
        }
    }
    public string Error
    {
        get { throw new NotImplementedException(); }
    }
    public string this[string propertyName]
    {
        get
        {
            return (!errors.ContainsKey(propertyName) ? null :
                String.Join(Environment.NewLine, errors[propertyName]));
        }
    }
}

我想在我的类中创建一个方法,在这个方法中,我将使用foreach循环或更好的LINQ从Dictionary中读取所有内容。我该怎么做呢?

我的想法,它不能正常工作

public void ReadAllErrors()
    {

        StringBuilder sb = new StringBuilder();
        foreach (string propertyName in errors.Keys)
        {
            sb.AppendLine(propertyName + "t");
            foreach (List<string> list in errors.Values)
            {
                foreach (string error in list)
                {
                    sb.AppendLine(error.ToString() + "n");
                }
            }
        }
        MessageBox.Show(sb.ToString());
    }

谢谢!

我首先要说的是,这个Product : IDataErrorInfo在我看来并不是最优雅的架构,无法完成我认为您正在努力完成的任务。如果有的话,应该将与错误相关的方法和字段移到基类(而不是接口)中,否则您将在每个类中重复所有这些逻辑。

但是为了回答你的直接问题,你可以修复你的ReadAllErrors()函数如下:

public void ReadAllErrors()
{
    StringBuilder sb = new StringBuilder();
    foreach (string propertyName in errors.Keys)
    {
        sb.AppendLine(propertyName + "t");
        foreach (string error in errors[propertyName])
        {
            sb.AppendLine(error.ToString() + "n");
        }
    }
    MessageBox.Show(sb.ToString());
}

你可以用LINQ创建类似的东西,像这样:

MessageBox.Show(string.Join("n", 
    errors.SelectMany(v => v.Value.Select(s => s)).ToArray()));

没有编译器在我面前,但我认为你只是一个小的逻辑错误,试试这个:

public void ReadAllErrors()
{

    StringBuilder sb = new StringBuilder();
    foreach (string propertyName in errors.Keys)
    {
      sb.AppendLine(propertyName + "t");
      foreach (string error in errors[propertyName])
      {
        sb.AppendLine(error.ToString() + "n");
      }
    }
    MessageBox.Show(sb.ToString());
}

看起来您对列表的迭代不正确。这能行吗?:

  StringBuilder sb = new StringBuilder();
  foreach (string propertyName in errors.Keys)
  {
    sb.AppendLine(propertyName + "t");
      foreach (string error in errors[propertyName])
      {
        sb.AppendLine(error);
      }
  }

如果不是,你能解释一下你期望得到什么?

编辑:

linq查询可能是这样的:

MessageBox.Show(errors.Select(e => e.Key + "rn" + e.Value.Select(v => v + "rn")))

我想说原版更容易读懂。

你可以在某处注入SB…

相关内容

  • 没有找到相关文章

最新更新