0

I have a List<T> like shown below, the list can contain nulls, below is just an example.

contactEntries = new List<ContactEntries>();
contactEntries.Add(new ContactEntries() { isPrimary = true, contactPerson = ceo, telephone = telephone, telephone1 = telephone1, address = address, postalCode = postalCode, city = city, email = email, role = (Roles)role, contry = (Countries)country });

And here are the class

public class ContactEntries
{
    [DisplayName("Primary:")]
    public bool isPrimary { get; set; }
    [DisplayName("Contact person:")]
    public string contactPerson { get; set; }
    [DisplayName("Telephone:")]
    public string telephone { get; set; }
    [DisplayName("Telephone 1:")]
    public string telephone1 { get; set; }
    [DisplayName("Address:")]
    public string address { get; set; }
    [DisplayName("Postal code:")]
    public string postalCode { get; set; }
    [DisplayName("City:")]
    public string city { get; set; }
    [DisplayName("Email:")]
    public string email { get; set; }
    [DisplayName("Role:")]
    public Roles role { get; set; }
    [DisplayName("Country:")]
    public Countries contry { get; set; }
}

public enum Roles
{
    CEO = 0,
    IT = 1
}
public enum Countries
{
    Denmark = 0,
    Norway = 1,
    Sweden = 2
}

Below is where I need to check for nulls. Note that this is a form, and the class (_contactEntries) is in another class, therefore there are some accessibility problems

 private void WizardCreateOrder_Finish(object sender, EventArgs e)
    {
        // Add client
        MySQL.Clients.Insert.Client(_orgNo, _companyName, _ceo, _companyType, _country, _leadId, _countryCode, out int clientId);


        // Here I need to check for null

        // Add contact persons
        foreach (var entry in _contactEntries)
        {
            MySQL.Clients.ContactPerson.Insert.ContactPerson(entry.contactPerson, entry.telephone, entry.telephone1, entry.address, entry.postalCode, 
                                                             entry.city, entry.email, _country, _countryCode, entry.role.ToString(), 
                                                             entry.isPrimary.ToString(), DateTime.Now, clientId, _leadId);
        }
    }

My question is: how can I check all these elements inside the list for null in a way that I don't have to check them one by one, but for example use linq to output a boolean that tells if there are nulls or not.

  • 5
    `contactEntries.Any(e => e == null)`? – GSerg Jan 04 '21 at 16:20
  • It's not clear whether you want to know if one element is null, all elements are null, or want a list of which ones are null (but if the latter, presumably that's for another step that might be better rolled into the "find nulls" part of the process, if we know what it is) – Damien_The_Unbeliever Jan 04 '21 at 16:22
  • @GSerg This does not validate the properties – Nicklas Christensen Jan 04 '21 at 16:23
  • @Damien_The_Unbeliever I want to know if any element in the list is null – Nicklas Christensen Jan 04 '21 at 16:23
  • @NicklasChristensen Correct, because this is not what you asked for. The "elements inside the list" are `contactEntries[0]`, `contactEntries[1]` etc. The properties of elements inside the list is something else. – GSerg Jan 04 '21 at 16:25
  • @GSerg Sorry my bad, I want to check the properties for null. My bad – Nicklas Christensen Jan 04 '21 at 16:26
  • 1
    Does this answer your question? [How to check all properties of an object whether null or empty?](https://stackoverflow.com/questions/22683040/how-to-check-all-properties-of-an-object-whether-null-or-empty) – GSerg Jan 04 '21 at 16:26

2 Answers2

1

Write a method that checks a single object for nulls, then use LINQ to check all elements.

bool ContainsNull(ContactEntries item)
{
    return item == null 
        || item.contactPerson == null 
        || item.telephone == null
        || item.telephone1 == null
        || item.address == null
        || item.postalCode == null
        || item.city == null
        || item.email == null
        || item.roles == null
        || item.contry == null; //sic
}

Then to check the list:

bool hasNulls = contactList.Any(ContainsNull);
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • this always return false – Nicklas Christensen Jan 04 '21 at 17:21
  • No, it really doesn't-- it's not exactly a complicated piece of code. I suspect there is something wrong with the way you are testing or populating the data. Post the code you are using for testing including sample data, – John Wu Jan 04 '21 at 17:58
0

You can use Reflection to achieve that. Reflection is a C# functionality that allows the code to access itself in runtime for setting values in runtime, reading properties or event creating properties on the fly, but be aware that reflection can be very slow depending of what you are doing.

Remember that only reference types like nullable<T>, strings and objects can be null, value types like, bool, int, double, etc has default values

 public bool CheckAnyNull(ContactEntries contactEntries)
 {
     // Get all properties of the class an iterates
     foreach (var item in contactEntries.GetType().GetProperties())
     {
         // Check if property is null
         if (item.GetValue(contactEntries) == null)
             return true;
     }

     return false;
  }
Andre.Santarosa
  • 1,150
  • 1
  • 9
  • 22
  • Please remember that this method is extremely slow!, compared to statically typed if statement. Before going for an "easier" solution read more about [Reflection](https://stackoverflow.com/a/35165431/2531209). – Tomasz Juszczak Jan 04 '21 at 16:53
  • @Andre.Santarosa one thing I forgot to mention is that the class (ContactEntries) is not in another class and I'm calling this from a form therefore I get this error: Severity Code Description Project File Line Suppression State Error CS0051 Inconsistent accessibility: parameter type 'Functions.Controls.DataEntry.ContactEntries' is less accessible than method 'CreateOrder.CheckAnyNull(Functions.Controls.DataEntry.ContactEntries)' CRM D:\Programmering\CRM IT\CRM\CRM\CreateOrder.cs 96 Active – Nicklas Christensen Jan 04 '21 at 16:54
  • Hello, @TomaszJuszczak yeah, I know that reflection is really slow but the OP asked for a way of check all nullable properties without checking one by one – Andre.Santarosa Jan 04 '21 at 17:00
  • @NicklasChristensen check if the method is more accessible than the ContactEntries property, if you have any trouble, post the full code on the question – Andre.Santarosa Jan 04 '21 at 17:03
  • Try set `CheckAnyNull` as `private` – Andre.Santarosa Jan 04 '21 at 17:34