Code Contracts - nice, on the edge, but not ready for prime time?
I got really captivated by code contracts introduced in .NET 4 (though with the help o开发者_如何学JAVAf DevLabs). But one fine print cooled me off quite a bit. Here is what it says:
- There is currently no workaround the problem when postconditions are called outside of lock in a thread-safe method except for not using them.
- .NET relies on a binary rewriter thus making the build slower.
- Using code contracts may also incur a runtime performance hit.
- Can't be used for security-sensitive checks because they can be circumvented at runtime by handling the ContractFailed event.
The biggest for me is the first one. I don't know if anyone write single-threaded apps anymore. So if code contracts are not able to support multi-threading, I don't see much use of them. Or maybe I shouldn't be stressed too much about that because postconditions are for asserting the internals of the method itself, which can be unit-tested.
BTW, I haven't found anything and I didn't try to disassemble my code to see where preconditions are injected. I suppose in a simple method when lock() goes first, it's simple to inject checks right after it but in a rather complicated method, when locking occurs somewhere in the middle, it may be an issue. Or if some other mechanisms other than lock() are used.
You seem to be confusing "writing multi-threaded apps" with "making every class thread-safe". Leaving aside the tricky question of defining the term "thread safety" I would suggest that very few of your classes should use locking in most apps.
Generally I write lots of classes which make no attempt to be explicitly thread-safe, but equally don't have any thread dependencies. They assume that if you're going to use them from multiple threads, you'll only do so from one thread at a time, with appropriate memory barriers to make sure changes made in one thread are visible in whatever thread next uses them.
There are then relatively few classes which perform the necessary coordination.
Now, it's possible that the problems with Code Contracts will make those few classes sufficiently weak as to make the whole think come tumbling down... but I wouldn't assume that to start with.
I'm somewhat warier of the issues Code Contracts will face with the C# compiler doing more and more work rewriting your code... I don't know whether the Contracts team has addressed issues of iterator blocks yet, but even if they have they'll have to do so again when C# 5 comes out with async methods...
There is currently no workaround the problem when postconditions are called outside of lock in a thread-safe method except for not using them.
Not really a problem—if you do a check yourself outside of a lock statement in thread-safe method you can run into a problem as well. Adjust your implemenation for this little 'limitation'. The question is how code rewriter going to know that you must be locking a resource? I think this limitation will stay on for a long time.
.NET relies on a binary rewriter thus making the build slower.
Yes, some IL has to be evaluated, generated, and saved to inject some IL build new dependencies = more time of course.
Using code contracts may also incur a runtime performance hit.
Also not unusual or a problem, more code (generated for the code contracts) = slower. You just have more code basically and what you may be running through a proxy class as well so there is more code + possible proxy.
Can't be used for security-sensitive checks because they can be circumvented at runtime by handling the ContractFailed event.
Yes don't do that. You don't even have to disaasble/reassemble the assembly to skip a potential security check. Keep any security related control flows on the server (be it web or db) if possible, or try to obfuscate your code to your best ability if local.
精彩评论