我有一个字典对象如下:
private Dictionary<String, List<String>> errors =
new Dictionary<string, List<string>>();
我在我的类Product中实现了IDataErrorInfo。其中存储了错误验证属性(Id,Name)的Dictionary<String, List<String>> errors
。如果我们将字典视为结构,那么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());
}
谢谢!
答案 0 :(得分:0)
在我面前没有编译器,但我认为你只有一个小的逻辑错误,试试这个:
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());
}
答案 1 :(得分:0)
IIUC看起来你正在错误地迭代列表。这会有用吗?:
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 + "\r\n" + e.Value.Select(v => v + "\r\n")))
我说原版更具可读性。
你可能会把SB注入某处......
答案 2 :(得分:0)
我首先要说的是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()));