In what circumstances can those things be null? If nulls would indicate a bug in the code then you could use code contracts. They will pick it up if you get nulls during testing, then will go away in the production version. Something like this:
using System.Diagnostics.Contracts;
[ContractClass(typeof(IContactContract))]
interface IContact
{
IAddress address { get; set; }
}
[ContractClassFor(typeof(IContact))]
internal abstract class IContactContract: IContact
{
IAddress address
{
get
{
Contract.Ensures(Contract.Result() != null);
return default(IAddress); // dummy return
}
}
}
[ContractClass(typeof(IAddressContract))]
interface IAddress
{
string city { get; set; }
}
[ContractClassFor(typeof(IAddress))]
internal abstract class IAddressContract: IAddress
{
string city
{
get
{
Contract.Ensures(Contract.Result() != null);
return default(string); // dummy return
}
}
}
class Person
{
[ContractInvariantMethod]
protected void ObjectInvariant()
{
Contract.Invariant(contact != null);
}
public IContact contact { get; set; }
}
class test
{
private test()
{
var person = new Person();
Contract.Assert(person != null);
if (person.contact.address.city != null)
{
// If you get here, person cannot be null, person.contact cannot be null
// person.contact.address cannot be null and person.contact.address.city cannot be null.
}
}
}
Of course, if the possible nulls are coming from somewhere else then you'll need to have already conditioned the data. And if any of the nulls are valid then you shouldn't make non-null a part of the contract, you need to test for them and handle them appropriately.