I have seen couple of posts regarding usage of Debug.Assert in C#.
But I still have one doubt, may be its repeated, but I need to ask.
Is there a strict rule that Debug.Assert should be used only for checking members of a class or used to check parameters to a public method?
Or Can i Use Debug.Assert where ever I want, and to check whichever condition?
Thanks
sandeep
Is there a strict rule that Debug.Assert should be used only for checking members of a class or used to check parameters to a public method?
Do not use Debug.Assert() to check parameters to a public method. Parameters should be checked in both debug and release builds.
You should use an explicit if followed by thowing ArgumentNullException, ArgumentOutOfRangeException or ArgumentException for invalid parameters.
Alternatively, use Code Contracts to express the parameter preconditions using Contract.Requires().
For further reference, see this thread: When should I use Debug.Assert()?
Other than that, then you can use Debug.Assert() wherever you want, but be aware that it might take a little more setting up for Asp.Net: Is it worth using Debug.Assert in ASP.NET?
Also see here: http://gregbeech.com/blog/how-to-integrate-debug-assert-with-your-asp-net-web-application
You can use it wherever you want. Just be aware that it's a debug check. So it's checked only at development time while you test it. If you need your program to actually change behaviour based on a condition, you still need additional ifs.
Read the coding guidelines over at Microsoft and try to use tools like the static code analysis or Visual Studio (formerly FxCop) and StyleCop to have an automated way of checking your code quality and common mistakes.
Related
One of my classes has a horrible requirement that resolving one of it's fields requires a service to be brought in by Dependency Injection, which is obviously not possible in a model in the standard Equals() and GetHashCode() calls. (Yes, I'd prefer it not to, bad practice etc, but I'm kind of stuck with it as a business requirement, unfortunately)
I can solve this by creating a Comparer class using IEqualityComparer<T>, but this leaves me with the default Object.Equals() and GetHashCode() being implemented, which may give misleading results when called.
As the presence of the IEqualityComparer is kind of 'hidden' unless you know about it, is it reasonable practice to override the Equals() and GetHashCode to return an exception to say that comparisons should use the Comparer? (Maybe just an Assert so that it only dies in debug/tests)
Throwing an exception like NotSupportedException is better than giving an incorrect answer, although since this is a class, arguably reference equality would suffice as the default, just using the external equality comparer for the custom functionality. But if that is going to cause confusion (in particular with people accidentally using the default API when they should be using the custom one); I wouldn't hesitate. The main problem you'll see is things like Contains checks blowing up, since classes aren't often used as dictionary keys.
As for only doing this in DEBUG builds... well, if it is wrong: it is wrong. If there's a scenario you aren't currently testing but that is used in prod, IMO it is better to become aware of that fact than to not. Although perhaps you might use an environment variable it similar to disable it in case you can't conveniently deploy a fixed build at short notice.
If I'm comparing two mutable objects, I would expect reference equality to be used by default. For records or structs I would expect value equality. For immutable objects I would probably expect value equality, but it depend a bit more on the context.
So I would only throw exceptions or use Debug.Asserts if I was sure reference equality is never the correct thing to use. And in that case I would be extra careful to document and highlight this unexpected behavior.
I would prefer exceptions over a Debug.Assert, since testing is usually done on release builds. And you want to find and fix these kinds of problems, since they most likely indicate a programming bug. There is also Trace.Assert, but I would probably not recommend it since it will make things like automated testing more difficult.
When should I debug.assert over code contracts or vice versa? I want to check precondition for a method and I am confused to choose one over the other. I have unit tests where I want to test failure scenarios and expect exceptions.
Is it a good practice to use Debug.Assert and Code contract on the same method. If so what would be the order in which the code should be written?
Debug.Assert(parameter!= null);
Contract.Requires<ArgumentNullException>(parameter != null, "parameter");
or
Contract.Requires<ArgumentNullException>(parameter != null, "parameter");
Debug.Assert(parameter!= null);
Is there any rationale behind it?
These are different things. A debug assert is only executed when the code is compiled as debug and therefore will only check/assert under debug. The idea is to use this for "sanity checks" for code you are developing. Code contracts can be used in either debug or release. They assure that pre and post conditions of methods comply with the expectations of the method (meet the contract). There is also a testing framework that provides similar functionality, designed for checking test compliance.
Use Debug.Assert when you want ensure that certain things are as you expect when developing the code (and in later maintenance development).
Use code contracts when you want to assure that conditions are true in both debug and release. Contracts also allow certain forms of static analysis that can be helpful in verifying that your program is "correct".
Use the Testing framework assertions when creating unit tests.
Personally, I wouldn't use both Debug.Assert AND Code Contracts to enforce preconditions in newly written code - IMO Code Contracts supercede Debug.Assert, as they offer a more comprehensive suite of checks, not to mention the benefit which can be gained from the static checking which can be performed before the code gets to run time. Maintaining duplicate precondition checks in both the Debug.Assert and Contracts will be cumbersome.
Rationale:
You don't need to re-code any legacy preconditions you may have coded in Debug.Assert or throw code - you can keep the existing precondition check code and terminate it with Contract.EndContractBlock()
You can get the same unchecked 'release mode' behaviour when System.Diagnostics.Debug is built without /d:DEBUG if you build with contract run time checking set to None. Ref 6.2.1 in the Docs
Contracts allows a dev to be more expressive in code as to 'why' an invalid state has been detected - e.g. was it directly because of an out of band parameter (Contract.Requires). Otherwise Contract.Assert or Contract.Assume can check general state, and the "guaranteed correctness" of state on leaving a method can be expressed using Contract.Ensures. And Invariants express that the state must be held at all times.
And best of all, Static checking can enforce these Contracts as you build your code - this way you have the chance to pick up the bug through a design time or compile time warning instead of having to wait for run time. Contract Checks can be added to your Continuous Integration to look for non-compliance.
One caveat : If you are going to write Unit Tests which deliberately violate contracts, you may need to deal with ContractException - Jon Skeet explains this well here. e.g. Wire up a Contract.ContractFailed handler in your test setup to a handler which calls SetHandled and then throws a public Exception which you can catch and assert in your UT's.
When Debug.Assert() method calls exist in source code and I compile in release mode, does the compiler generate the IL for the Debug.Assert() even though it's not called?
One of our developers added an Assert recently that displays information about our internal security. Could someone look at the release mode IL and figure out the text for the assert?
No, the members of the Debug class (with the ConditionalAttribute attribute) do not emit IL. There is no explicit mention on MSDN, however the following two quotes imply the behaviour quite well, so to augment Roy's answer:
If you use methods in the Debug class to print debugging information
and check your logic with assertions, you can make your code more
robust without affecting the performance and code size of your
shipping product.
So, no size difference implies no output from these whatsoever, and
The ConditionalAttribute attribute is applied to the methods of Debug.
Compilers that support ConditionalAttribute ignore calls to these
methods unless "DEBUG" is defined as a conditional compilation symbol.
Refer to a compiler's documentation to determine whether
ConditionalAttribute is supported and the syntax for defining a
conditional compilation symbol.
Which means that, at the compiler level, these calls won't even be considered (when DEBUG is not defined.)
It does not by default, unless you define the DEBUG symbol (and by default, for Release that is turned off).
To verify, open your Project Properties and select the Build pane in Visual Studio. It will show the checkbox "Define DEBUG constant". If it is turned on for Release, then asserts will fire; otherwise, they won't.
I would like a way to get warnings when an object reference could potentially throw a Null Reference Exception, so that I can write defensive code for these.
I have looked at Resharper, but didn't see anything there that accomplishes this.
Code Contracts is probably a non-starter; the application is quite large, and it's written in .NET 3.5, before Code Contracts became officially available.
Resharper does in fact accomplish something like this. Possible NullReferenceExpections are highlighted in the IDE in blue, with tooltips when you hover over them.
Resharper then keeps track of potential errors and warnings in it's own inspection results window (separate from Visual Studio's compiler errors and warnings).
Generally speaking, unless you specifically initialized an object, It can always have the potential to throw a null object reference, at least as far as the compiler is concerned.
in order for an algorithm to check whether a reference to the object can potentially be null, it would have to traverse every possible path that your program can take, and that includes paths in any external libraries that you may be using. Even for the simplest of programs, such an algorithm would kill the performance of your compiler.
I'm against the idea of blindly defending against null for each field available in the code and inside each method.
The following help me deciding about where to check against null values:
1- Who will be invoking your methods?
If a method is private and you have control over how's it's being accessed, I don't see it makes sense to protect against null checks unless it's part of the method's logic to expect null values.
If a method is exposed to the public (Such as an API), then of course null checks should be a huge concern.
2- Software Design:
Image you have are calling method1(fromAnimalToString(animal)); and for some reason fromAnimalToString() never returns null (Though might return an empty string instead).
Then in such case, it wouldn't make sense to check animal != null in method1()'s body
3- Testing:
In software engineering, it's almost impossible to test all possible scenarios that can ever execute. However, test normal and alternative scenarios and make sure the flow is as expected.
In Java, you explicitly define what exceptions are thrown using the "throws" keyword. That way, anyone calling your method knows what to catch.
Is there something in C#? If not, how do I know what exceptions to catch, or how do I let others know what exceptions to catch?
Also, if I am defining an interface, is there a way to say "methodX() should throw this exception on error"?
There is nothing equivalent in C#: The Trouble with Checked Exceptions
Other than documentation, there is no way to declare an interface to say "methodX() should throw this exception on error".
C#/.net does not have checked Exceptions, they proved to be less useful in large scale systems than first thought. In a lot of projects the time to maintain the check exception specs was a lot greater than the debugging time saved by having them.
Checked Exceptions seem like a good ideal until you have methods that can take delegates or calls into object you pass in. Take a simple case, the Sort() method on a list can’t know what exceptions it will throw, as it does not know what exceptions the Compar() method on the objects being sorted will throw.
So the spec for the exceptions a method may throw must be able to include information on how exceptions are populated from pass in objects and delegates. No one knows how to do this!
However there are tools that you check if you are catching all exceptions – see Exception Hunter by Red Gate. I personally don’t see much value in these tool, however if you like checked exceptions you may find them useful. ==> Looks like Exception Hunter wasn't too useful, so Redgate discontinued Exception Hunter a long while ago:
This feature is not available in C#. You can make proper XML documentation (3 slashes ///) and state what exceptions are being thrown.
This will be picked up by the IntelliSense mechanism and will be visible for the users of the class/method before they use it.
C# does not support this. (Not that I know anyway).
What you can do is use Xml Comments so that while calling you methods this data will be shown by intellisense.
As far as I'm aware there is no throws declaration in C# you can document your method indicating that it throws an exception but no forced error handling.
C# doesn't support checked exceptions. The language designers consider checked exceptions in the way java uses them a bad idea.
Some workarounds
Let me cite this medium article: It's almost 2020 and yet... Checked exceptions are still a thing
Among the many reasons why it's a bad idea, putting the checked exceptions in the contract (interfaces):
makes it impossible to change the implementation of an interface with a different one which throws different exceptions
exposes implementation details
a change of the checked exceptions of an API interface, makes it necessary to change the whole chain of interfaces in the call stack
For example, imagine that you are implementing a repository based on SQL Server, so you expose all kind of SQL Server specific exceptions. Then you want to move it to MySQL or Cosmos BD. Of course:
the implementation can't be changed to a new one that need to throw different exceptions. Also related to this, if you have different implementations of the storage, you can't just change them by configuration, but you need to have different compilations of the code for each storage backend
this is the explanation for 1: as the interface showed the implementation details (SQL Server exceptions) know you can't just change it
if you need to make the change, prepare to change the interface at all levels, since the API that uses the database up to the lates consumer in the call stack chain.
The articles cited above includes pointers to many explanations to discourage the use of checked exceptions, included this by the creator of C#: The trouble with checked exceptions