using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public class SomethingNested
public string SomeString { get; set; }
public int SomeNumber { get; set; }
public bool SomeBoolean { get; set; }
public List<string> SomeStringList { get; set; }
public SomethingNested SomethingNested { get; set; }
public string SomeString { get; set; }
public int SomeNumber { get; set; }
public bool SomeBoolean { get; set; }
public List<string> SomeStringList { get; set; }
public static void Main()
var myWidget = new MyWidget
SomethingNested = new SomethingNested
SomeStringList = new List<string> { "a", "b", null }
AssertPropertiesAreNonNull(myWidget, false);
private static void AssertPropertiesAreNonNull<T>(T obj, bool onlyRequiredProperties = true)
var objType = obj.GetType();
var properties = onlyRequiredProperties ? objType.GetProperties()
.Where(x => x.GetCustomAttributes(false).OfType<RequiredAttribute>().Any()) :
foreach (var property in properties)
var propValue = property.GetValue(obj, null);
var elems = propValue as IList<object>;
foreach (var item in elems)
AssertPropertiesAreNonNull(item, onlyRequiredProperties);
if (property.PropertyType.Assembly == objType.Assembly)
AssertPropertiesAreNonNull(propValue, onlyRequiredProperties);
Console.WriteLine($"Evaluating {property.Name}...");
var errorMessage = $"Property '{property.Name}' is null!";
Console.WriteLine(errorMessage);