Shirt and tie, green tank top, brown jacket with leather patches on the elbows and horn rimmed spectacles. The image of my college maths tutor yelling “break the line, change the sign!” is still burnt into my brain.
Nevertheless De Morgans’s Law is one of those things from my days as an electronics research technician that’s still useful today – so it was worth it.
I needed to change an if statement around. Originally it was like this;
if (null == cert || !cert.HasPrivateKey) doMainPart() else doElsePart()
But I wanted to switch the main and else part around, so I wanted to reverse the result of the condition. I could have done this…
if ( !(null == cert || !cert.HasPrivateKey))
But instead I employed De Morgan’s Law. To invert the meaning of the entire condition the first step is to invert the meaning of each individual term of the condition. So:
null == cert
becomesnull != cert
!cert.HasPrivateKey
becomescert.HasPrivateKey
The second step is to change the operators that combine the terms, so OR
becomes AND
and vice-versa.
Thus (null != cert && cert.HasPrivateKey)
gives the exact opposite result to (null == cert || !cert.HasPrivateKey)
.
if (null != cert && cert.HasPrivateKey) doElsePart() else doMainPart()
It’s really easy to tie yourself in knots with this kind of stuff, remembering De Morgan’s law can save a lot of heartache.
If you’re wondering why it’s “break the line, change the sign” this is because of the way boolean logic is written is electronics: if you want to invert the meaning of something you don’t put a ! in front of it, you draw a line over the top of it.
So our condition would have started as:null == cert ||
cert.HasPrivateKey
We then want to invert the entire operation, so we draw a line right over the top…null == cert ||
cert.HasPrivateKey
Now we apply De Morgans’s Law, we break the line and change the sign.
null == cert
&&
cert.HasPrivateKey
Of course the two inversions on the right-hand side cancel each other out, so we finish with:null == cert
&& cert.HasPrivateKey
Of in C#null != cert && cert.HasPrivateKey