Debug.Assert

  • Thread starter Thread starter Peter Morris
  • Start date Start date
P

Peter Morris

In Delphi I used to use Assert as a development aid. During debug it would
ensure that certain conditions were met but in the Release build the Asserts
were not compiled into the application. I am assuming this is the same with
..NET too? Debug.Assert isn't compiled into a Release build?

The other thing I am curious about is this

public void DoSomething(Person p)
{
if (p == null)
throw new ArgumentNullException("P");
....
}

Why do people tend to use exceptions such as ArgumentNullException instead
of something like this which I presume gets skipped in Release build and is
also quicker to type?

public void DoSomething(Person p)
{
Debug.Assert(p != null, "P is null");
....
}



Pete
 
Debug.Assert is marked with [Conditional("DEBUG")], which means that
calls to it only get compiled if the caller has the DEBUG symbol defined.

So yes; calls to Debug.Assert will not be compiled into a release build,
as long as you don't define "DEBUG" ;-p

Re the null check; Well, I guess it depends on what the code is. If it
is a library you can't trust the caller, so you'd need to still check.
For UI work, you could argualy use an Assert, but you'd need to be sure
that you have 100% code coverage. But this check will be ridiculously
quick, so I'd probably leave it in in most cases.

Re typing, well, you could probably use a custom snippet if you
wanted... in C# 3 you could also use an extension method (confusing
fact: you can call extension methods on null instances) - so you might have:

person.ThrowIfNull("person");

(note I renamed the variable to be meaningful; I'd recommend this...
it'll save pain in the long run).

Marc
 
Why do people tend to use exceptions such as ArgumentNullException instead
of something like this which I presume gets skipped in Release build and
is also quicker to type?

public void DoSomething(Person p)
{
Debug.Assert(p != null, "P is null");
....
}

It really boils down to whether it's something that can happen in your
release build or not. If you're serving up a release library to a 3rd party
in particular then you never know what someone might pass. OTOH, if it's
only being consumed by your own code, then an "Assert()" is usually fine
IMO. Some would still argue that an exception should be used however if only
to catch your own mistakes (those that make it into the release build by
accident). In my long experience however, I don't recall ever encountering
this situation. I therefore rely on "Assert()" extensively for all my own
code. Maybe it's not quite as safe, but relying on exceptions to catch
programmer errors in a release build just rubs me the wrong way. GIGO should
be understood by developers who need to apply diligence when they program.
An "Assert()" is normally sufficient for this IMO (even for 3rd party
developers for that matter) but it's really a personal choice.
 
Those were the rules I have imposed on myself in the past, so I am pleased
to see a couple of replies confirming that I am doing the right thing :-)
(note I renamed the variable to be meaningful; I'd recommend this... it'll
save pain in the long run).

I am more idle when writing in newsgroups ;-)


Thanks

Pete
 
Re the null check; Well, I guess it depends on what the code is. If it
is a library you can't trust the caller, so you'd need to still check.
For UI work, you could argualy use an Assert, but you'd need to be sure
that you have 100% code coverage. But this check will be ridiculously
quick, so I'd probably leave it in in most cases.

Technically, there's also a third option - Trace.Assert, which is in
release builds by default.

Even so, using ArgumentException is the standard .NET pattern, and I
don't see any good reason for avoiding it (saving 3 lines of code is
not a good reason). Also, VS Code Analysis has an option to enforce
validation of arguments, and the only way it supports is explicit
check and throw ArgumentNullException.
 
I know it has been discussed before, but a language tweak would be very
welcome here; something like:

public void DoSomething(Person !p) {...}

And let the compiler worry about it.

(although perhaps more meaningful syntax)
 
I know it has been discussed before, but a language tweak would be very
welcome here; something like:

public void DoSomething(Person !p) {...}

And let the compiler worry about it.

(although perhaps more meaningful syntax)

I'd go for "Person! person" to mirror "int? value".
Mads and I discussed this a bit back in 2005. It's the obvious "4th
box" to fill in for the value/reference, nullable/non-nullable matrix.

I'd be happy if it were just a shortcut for automatically creating
null-checking code at the start of methods, even without the
"correctness proving" which would also be possible.

Jon
 
I've seen (somewhere) an example of using something like PostSharp to
enforce it

[NotNull<Person>("person")]
public void DoSomething(Person person)
{
}

But at best it makes me mmm and ahhh a bit, doesn't jump out at me as a
great solution.
 
Marc said:
Debug.Assert is marked with [Conditional("DEBUG")], which means that
calls to it only get compiled if the caller has the DEBUG symbol defined.

So yes; calls to Debug.Assert will not be compiled into a release build,
as long as you don't define "DEBUG" ;-p

Re the null check; Well, I guess it depends on what the code is. If it
is a library you can't trust the caller, so you'd need to still check.
For UI work, you could argualy use an Assert, but you'd need to be sure
that you have 100% code coverage. But this check will be ridiculously
quick, so I'd probably leave it in in most cases.

Re typing, well, you could probably use a custom snippet if you
wanted... in C# 3 you could also use an extension method (confusing
fact: you can call extension methods on null instances) - so you might
have:

person.ThrowIfNull("person");

I wrote an evil little extension method a while ago:

[MethodImpl(MethodImplOptions.NoInlining)]
public static void CheckForNull(this object o)
{
if (o != null) return;
StackFrame frame = new StackFrame(1, true);
byte op =
frame.GetMethod().GetMethodBody().GetILAsByteArray()[frame.GetILOffset()
- 6];
throw new
ArgumentNullException(frame.GetMethod().GetParameters().Length <=
(4 - (frame.GetMethod().IsStatic ? 0 : 1)) ?
frame.GetMethod().GetParameters()[op - (2 +
(frame.GetMethod().IsStatic ? 0 : 1))].Name :
"An argument was null, but I'm not sure which one.");
}

No need to pass the parameter name.

Alun Harford
 
Jon said:
I'd go for "Person! person" to mirror "int? value".

This is exactly what Spec# uses. I *really* want that in C# 4 (or a C#3
version of Spec#)

Alun Harford
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top