C#:列出类的所有空属性的LINQ查询

4

我有一个类如下:

public class Test
{
    public string STR1{ get; set; }
    public INT INT1{ get; set; }
    public DOUBLE DBL1{ get; set; }
    public DATETIME DT1{ get; set; }
}

通常,在保存对象之前,我需要检查此类中的所有属性,并在存在任何空/ null属性时返回警告消息。可以通过像这样简单地检查每个属性来轻松完成此操作:

if (string.IsNullOrEmpty(t.STR1))
    return "STR1 is empty"
if (t.INT1 == 0)
    return "INT1 = 0";
if (t.DBL1 == 0)
    return "DBL1 = 0";
if (t.DT1 == DateTime.MinValue)
    return "DT1 is empty"

但是如果我的类有更多属性,实际上现在它包含大约42个属性,并且仍在增长。所以我在考虑一种更“清洁”的方法来执行此检查,并且我找到了这个主题,它与我的问题非常相似:Reflection (?) - Check for null or empty for each property/field in a class? 但是这个解决方案不符合我的需求,因为我必须列出等于null/空字符串/0/DateTime.MinValue的值。
相信我,我想发布我的“尝试代码”,但我无法为此任务想出一个合理的LINQ查询(我是C#的新手)。
非常感谢任何帮助!

2
所以不要使用LINQ查询,而是使用普通的循环和一些反射?检查每个属性的类型并使用适当的默认值。或者只需使用default()进行检查,因为这是您每次使用的内容。 - Jeroen Vannevel
1
@hoangnnm,您可以在属性上使用默认值的属性。然后检查属性的当前值是否等于其默认值。 - m1o2
@JeroenVannevel 对不起没有提到,我确实使用了一个普通的循环和一些反射,就像你上面说的那样。我在问题中的示例并不是我当前正在使用的方式,它只是表达我的问题的一种方式。我的真正关注点是我能否使用LINQ来实现这个。 - NeedAnswers
但是默认值也是一个好主意,谢谢! - NeedAnswers
1个回答

7

因为您需要测试不同类型的对象,所以可以将链接问题中的解决方案与使用 dynamic 调度到正确方法相结合。

首先,为每种类型定义一个重载方法。

private static IsEmpty(string s) { return string.IsNullOrEmpty(s); }
private static IsEmpty(double f) { return f == 0.0; }
private static IsEmpty(int i) { return i == 0; }
private static IsEmpty(DateTime d) { return d == DateTime.MinValue; }

现在您可以在您的检查中使用这些方法:
List<string> emptyProperties = typeof(MyType).GetProperties()
    .Select(prop => new { Prop = prop, Val = prop.GetValue(obj, null) } )
    .Where(val => IsEmpty((dynamic)val.Val) // <<== The "magic" is here
    .Select(val => val.Prop.Name)
    .ToList();

代码中的棘手部分将值转换为dynamic,然后告诉运行时查找最适合它的IsEmpty方法。这种方法的缺点是编译器无法确定是否会找到该方法,因此您可能会在运行时遇到意外类型的属性而导致异常。
您可以通过添加一个接收object的全捕获方法来防止这些失败,就像这样:
private static IsEmpty(object o) { return o == null; }

1
哇,我无言以对,这正是我所需要的,非常感谢! - NeedAnswers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接