【发布时间】:2019-12-12 07:06:11
【问题描述】:
我有一个如下所示的 Data 类。
public class Data
{
public string Dt1 { get; set; }
public string Dt2 { get; set; }
public string Dt3 { get; set; }
public string Dt4 { get; set; }
public string Dt5 { get; set; }
}
以及它的类对象列表,以及以下示例数据。
var list = new List<Data>
{
new Data() { Dt1 = "DtA", Dt2 = string.Empty, Dt3 = "-", Dt5 = "DtC" },
new Data() { Dt1 = "DtB", Dt2 = string.Empty, Dt3 = string.Empty, Dt5 = "-" },
new Data() { Dt1 = "DtC", Dt2 = "-", Dt5 = "-" },
new Data() { Dt1 = "DtD", Dt2 = string.Empty, Dt3 = "DtX", Dt5 = string.Empty },
new Data() { Dt1 = "DtE", Dt3 = "-" }
};
我有一个“无效”字符串列表,如下所示。
var invalid = new List<string>() { string.Empty, "-", null };
现在,我想从上面的列表中识别出至少包含一个 valid 字符串的属性名称,然后用这些属性名称创建一个List<string>。如果我们考虑上面的样本数据,你可以看到,
- 所有
Dt1值均有效。 - 所有
Dt2值均无效。 -
Dt3至少有一个有效值。 -
Dt4从未被赋值,因此所有值都无效。 -
Dt5至少有一个有效值。
所以,我的结果列表应该是
Dt1、Dt3、Dt5
我的方法是编写一个函数来识别字符串中是否至少有一个有效值,然后使用它检查列表的每个属性。
public static bool IsDataValid(List<string> data, List<string> invalid)
{
foreach (var item in data)
{
if (!invalid.Contains(item))
{
return true;
}
}
return false;
}
那么,
var invalid = new List<string>() { string.Empty, "-", null };
var result = new List<string>();
if (IsDataValid(list.Select(x => x.Dt1).ToList(), invalid))
{
result.Add("Dt1");
}
if (IsDataValid(list.Select(x => x.Dt2).ToList(), invalid))
{
result.Add("Dt2");
}
if (IsDataValid(list.Select(x => x.Dt3).ToList(), invalid))
{
result.Add("Dt3");
}
if (IsDataValid(list.Select(x => x.Dt4).ToList(), invalid))
{
result.Add("Dt4");
}
if (IsDataValid(list.Select(x => x.Dt5).ToList(), invalid))
{
result.Add("Dt5");
}
这确实有效,但对我来说有点“难看”。另外,我实际的 Data 类有 20 多个属性,所以我必须使用 20 个 if 语句,这又是糟糕的设计。
我想知道是否还有其他方法,尤其是我不必“硬编码” if 语句的方法。像下面这样我可以迭代类的属性并找出列表中哪些是有效的。
foreach (var prop in typeof(Data).GetProperties())
{
// How do I do a `.Select()` here?
}
【问题讨论】:
-
不完全。我知道如何获取一个类的属性列表。我的问题是,由于获得的属性名称将是
string,我不能做类似list.Select(x => x.(property name)的事情,因为这显然行不通。 -
不是 100% 确定你将如何实现它,但这看起来很像在 MVC 中广泛使用的
IValidatable/ 带有数据注释。也许您可以在这里使用IValidatable,或者考虑创建它的自定义版本。当您进行验证检查时,您必须有验证规则,然后是yield return -
那么你想要这样的东西吗? dotnetfiddle.net/TCx5HN 我很快就搞定了,通过手动循环替换 LINQ 查询可能会提高效率...
-
@dbc 这看起来很有希望。让我仔细看看。
-
@Sach - 我通过用一个简单的循环替换 LINQ 查询 +
Distinct()加快了速度。
标签: c# linq select properties