From time to time, I encounter annoying bugs in the .NET framework that the compiler cannot clearly point out at both compile time and runtime. This for example.
It states that if you wire up the MvcApplication.BeginRequest manually in Application_Start from Global.asax.cs, you'll get a NullReferenceException in System.Web.HttpRuntime.ProcessRequestNotificationPrivate.
Since there is no clear way to relate the error to the cause, it would be nice to be able to write something that states that if you wire up event MvcApplication.BeginRequest from MvcApplication.Application_Start, to throw an compile time error, forcing you to remove it and explain why.
You can implement a custom FxCop rule which checks if the handler is wired up as you said and include that rule in your code analysis ruleset. Check out the rule CA2001, it does something similar to what you want to achieve.
For information on implementing custom FxCop rules see http://www.binarycoder.net/fxcop/index.html.
Related
I'm about to embark on a new C# project. I was wondering what the difference is between using Code Contracts or Code Analyzers (in Roslyn). Am I misunderstanding the usage of each? Being a new project, I would like to maintain the integrity of the code. So I want other developers to adhere to specific code guidelines. I'll research each further, but I was wanting to get the opinion of the community first. Excuse the question, I'm still rather new to C# development.
They are two different tools.
Code Contracts is a way to declare and check... well, contracts, such as pre-conditions and post-conditions:
public class Foo
{
public Foo(object arg)
{
Contract.Requires<ArgumentNullException>(arg != null);
}
public object GetBar()
{
Contract.Ensures(Contract.Result<object>() != null);
// TODO:
}
}
CC check their conditions at run-time. This requires your assembly (not source code!) to be rewritten after compilation to inject appropriate calls into your code.
Code Analyzers use Roslyn to analyze source code while you're writing it.
They can help you to format code, to remind you to call Dispose on IDisposable, and so on, but they don't affect run-time behavior directly.
There are a number of analyzers, grouped by purpose into projects (like StyleCopAnalyzers), while Code Contracts is a standalone project.
(CC also have static analyzer, but I can't tell much here - it kills performance when used on real projects, so, for me it is usually turned off. Anyway, it is intended to check contracts.)
Code analyzers will analyze your code for common mistakes. They look at the structure of the code and the flow of data across to detect problems.
Another type of analyzers looks at the style (StyleCop for example), capitals, camel casing, prefixes, postfixes and what have you.
The third type are the code contracts you've mentioned, and this works slightly different. You declare the expected behavior of your code, for example what is expected of parameters passed into a method, which exceptions your code can throw etc. The contracts analyzer will then check whether calling code is passing in the right parameters (e.g. the analyzer will detect you passing in null and will raise an error if that's not allowed). At the same time it will check the "internal consistency" of your methods to ensure that you don't throw exceptions you're not allowed to throw. Depending on the implementation contracts can be validated at runtime or at compile time.
My library has some methods whose return value should never be discarded. Leaking them is a very popular mistake even for me, the author. So I want the compiler to alert programmer when it does so.
Such value may be either stored or used as an argument for another method. It's not strictly to use the stored value but if it's simply discarded it's 100% error.
Is there any easy to setup way to enforce this for my library users?
var x = instance.Method(); // ok
field = instance.Method(); // ok
instance.OtherMethod(instance.Method()); // ok
MyMethod(instance.Method()); // ok, no need to check inside MyMethod
instance.Method(); // callvirt and pop - error!
I thought about making IL analyzer for post-build event but it feels like so overcomplicated...
If you implement Code Analysis / FXCop, the rule CA1806 - Do not ignore method results would cover this case.
See: How to Enable / Disable Code Analysis for Managed Code
Basically, it's as simple as going to the project file, code analysis tab, checking a box and selecting what rules to error / warn on.
Basically tick the checkbox # 1, and then use 2 to get to a window where you can configure a ruleset file (this can either be one you share between libraries or something more global (if you have a build server, make sure its stored somewhere the build can get to, i.e. with the source not on a local machine).
Here's a ruleset with the rule I mean:
The Nicolai's answer enables ruleset for any types but I needed this check for only my library types (I don't want to force my library users to apply rule set on all their code).
Using out everywhere as suggested in the comments makes the library usage to hard.
Therefore I've chosen another approach.
In finalizer I check whether any method was called (it's enough for me to confirm usage). If not - InvalidOperationException. Object creation StackTrace is optionally recorded and appended to the error message.
User may call SetNotLeaked() to disable the check for particular object and all internal objects recursively.
This is not a compile-time check but it will surely be noticed.
This is not a very elegant solution and it breaks some guidelines but it does what I need, doesn't make user to view through unnecessary warnings (RuleSet solution) and doesn't affect code cleanliness (out).
For tests I had to make a base class where I setup Appdomain.UnhandledException handler in SetUp method and check (after GC.Collect) whether any exception was thrown in TearDown because finalizer is called from another thread and NUnit otherwise shows the test as passed.
I am implementing a error logger for a web shop and just logging a NullReferenceException in a specific class is only useful to a certain level. I am not really interested in how to prevent the exception, as I am aware of that, but sometimes it still happens thus the error logger.
Then the question is: How do I find the source of a System.NullReferenceException inside all the exception information.
Make sure you log the full stack trace. Assuming you've got debug information turned on (no reason not to for a web app...) you should be able to get to the line which caused the problem.
Of course, that won't always give you all the information you need, if you've got:
if (foo.Bar.Baz && person.Address.Road.Length)
in a single line... but it's the best starting point you'll get.
Additionally, adding argument validation to methods can make it a lot simpler to pin down what's wrong. Personally I'm a fan of helper methods for this. For example, in Noda Time we have Preconditions, so I can just call:
Preconditions.CheckNotNull(foo, "foo");
(which also returns the value of foo, which is handy in constructors which are copying arguments into fields).
The earlier you can detect the unexpectedly-null reference, the better.
If I understand the question correctly, in Visual Studio, go to Debug > Exceptions, and check all options to throw exceptions. This will allow you to see everything that is being thrown while debugging. You can possibly use the contents of InnerException to determine what the root location of the error is being caused.
I have the following code that generates a compiler error:
Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
ThrowHelper.ThrowInvalidCast(typeof(MyType), typeof(Boolean));
}
The compiler is complaining that not all code paths return a value. The problem here is that ThrowHelper will ALWAYS throw an error. It is a static class calling a static method.
I understand that I can satisfy the compiler with a silly "return true" after the ThrowHelper call, but that seems like unnecessary code. I know I can suppress warning messages, but when I tried to use the SuppressMessageAttribute it doesn't stop the compiler from complaining. Any way to suppress this error only for this method?
You could have the method in ThrowHelper only create the exception, not actually throw it.
Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
throw ThrowHelper.CreateInvalidCast(typeof(MyType), typeof(Boolean));
}
This would probably result in a better stack trace as well: it would point at ToBoolean, not at ThrowInvalidCast.
There is no way to suppress an error other than to fix it.
An error, by its nature, is indicating that the compiler believes it cannot generate valid code. The only way to suppress errors is to fix them. Just add the return statement it wants and then raise an issue on Microsoft Connect indicating that you believe the compiler is getting this one wrong.
I suspect, however, that this is expected behaviour as the compiler is not aware that the method you are calling will always throw and to determine that in a predictable manner for any possible call tree would be difficult, if not impossible (imagine if you called a chain of 20 methods before concluding with a throw).
A simple brain exercise why the requested feature could lead to problems. Imagine that ThrowHelper.ThrowInvalidCast is defined in some 3rd-party library. You might know that the method always throws and tell the compiler about it or a very advanced static analyzer might be able to determine that the method always throws at the moment the code is compiled.
Now some other developer deploys an updated version of that library. Now the method doesn't always throw. All of a sudden, there is a case that your method has no return path. Just to handle that case the compiler (or the runtime) would have to include a backup plan what to do in such a situation. Quite a lot of overhead for something that can easily be fixed by writing correct code.
UPDATE: Theoretically, C# could be extended to allow for methods with no return path. Eric Lippert mentioned that in a comment to Jon Skeet's answer here:
A "never" method would simply be a void method that is not allowed to have a reachable end point or any return statements. That solves the problem at compile time. At runtime, it's the verifier's responsibility to ensure that methods actually implement their return type semantics correctly; the verifier could similarly determine that there are no return instructions and that the end point is not reachable.
I am search a way to disable usage (**throw new exception **) of specific exception in our c# solution.
If can I configure c# compiler and show compiled error if somebody try to throw a specific exception or, maybe, can I call a utility and analyze compiled binaries and show message if the specific exception was raises in our solution?
I am not look run-time solutions. I want to check in "development" time.
Igor.
You may consider adding a custom rule(Warning/Error) to the FxCop and then build the solution after adding the FxCop project file into your solution.
If the exception in question is your own exception, you can decorate the exception class with the Obsolete attribute. Then the compiler will show a warning whenever the class is used.
[Obsolete("MyException is obsolete. Please use MyOtherException instead")]
public class MyException : Exception
{
}
Give Gendarme a look; I'm not sure how trivial it is to write a new rule that can do what you want, but I'm hoping it would be easy enough. Failing that, check out StyleCop.