Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# : LINQ query to list all empty properties of a class

I have a class like this :

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

Normally, before saving the object, i will have to check all the properties inside this Class, and return a warning message if there is any empty/null property. There is easy way to do this by simply check each property like this :

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"

But what if my class has more properties, actually it contains about 42 properties now, and still growing up. So i was thinking for a "cleaner" way to perform this check, and i found this topic which is quiet similar to my issue : Reflection (?) - Check for null or empty for each property/field in a class?

But this solution does not meet my need as i have to list the values that = null/empty string/0/DateTime.MinValue

Believe me, i wanted to post my "tried code" but i can't figure out a sensible LINQ query for this task (i'm a novice in C#)

Any help is greatly appreciated !

like image 673
NeedAnswers Avatar asked Mar 19 '23 04:03

NeedAnswers


1 Answers

Since you need to test objects of different types, you can combine the solution from the linked question with use of dynamic to dispatch to the proper method.

First, define an overloaded method for each type.

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; }

Now you can use these methods in your check:

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();

The tricky part of the code casts the value to dynamic, and then tells the runtime to find the most appropriate IsEmpty method for it. The downside to this approach is that the compiler has no way of telling whether the method is going to be found or not, so you may get exceptions at runtime for properties of unexpected type.

You can prevent these failures by adding a catch-all method taking object, like this:

private static IsEmpty(object o) { return o == null; }
like image 171
Sergey Kalinichenko Avatar answered Mar 31 '23 15:03

Sergey Kalinichenko