"Call-site Requires Checking" does not work on constructors.
-
21 Mei 2012 13:53
Hello,
I think that I found a bug in Code Contracts v1.4.50327.0 (and also in previous).
Consider the following scenario :
I have a Class1 in a project called "ClassLibrary1" :public class Class1 { public Class1(object o) { Contract.Requires<ArgumentNullException>(o != null); Console.WriteLine(o.ToString()); } public void Display(object o) { Contract.Requires<ArgumentNullException>(o != null); Console.WriteLine(o.ToString()); } }I compile this project with this following configuration (in Release) :
AssemblyMode : Standard Contract Requires
Perform Runtime Contract Checking : None
ContractReferenceAssembly : Build
I run the compilation and I put the compiled assemblies into C:\ClassLibrary1Folder\
After, I create a new project "ConsoleApplication1" (Console Application).
I add a file reference (and not a project reference !) to the ClassLibrary1.dll in the C:\ClassLibrary1Folder\.
In the Main() method I put the following code :static void Main(string[] args) { Class1 c = new Class1(null); c.Display(null); }I compile this project with this following configuration (in Debug) :
AssemblyMode : Standard Contract Requires
Perform Runtime Contract Checking : Full
Call-site Requires Checking : "Checked"
I run the console application, and I get a "NullReferenceException" !
It's strange... I should have an ArgumentException of the requires contracts...I look the compiled code of the Main() method of the ConsoleApplication, and I found that no "wrapper method" has been generated for the constructor for my required contract :
Is it a bug of Code Contracts ?
Thanks for your answers !
Best regards,
Gilles TOURREAU - MVP C#
Architecte logiciel/Consultant/Formateur Freelance
Blog : http://gilles.tourreau.fr
- MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
- MCITP : SQL Server 2008 Developper
- MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0
Semua Balasan
-
31 Mei 2012 20:44Pemilik
When the rewriter is running on your console application, it has to be able to find the contracts for referenced assemblies. I'm guessing that in the folder where you copied the runtime assemblies for your library, you did *not* put the contract reference assembly in that folder. If you change the properties for the library in the Code Contracts pane so that it builds a reference assembly and then copy the resulting assembly (ClassLibrary1.Contracts.dll) into the same folder as the runtime assembly, then the rewriter should find it. Please let me know if that isn't the case. (Or even if it does fix the problem!)
When you make a project reference instead of a file reference, then our msbuild magic does all of the right stuff in order to find the directories that are needed. You can probably see this if you look at the command line for ccrewrite that is in the output window.
Mike Barnett
- Disarankan sebagai Jawaban oleh Mike BarnettMicrosoft Employee, Owner 31 Mei 2012 20:45
- Saran Jawaban dibatalkan oleh Gilles TOURREAUMVP 12 Juni 2012 11:26
-
01 Juni 2012 7:45
Hello Mike,
"I'm guessing that in the folder where you copied the runtime assemblies for your library, you did *not* put the contract reference assembly in that folder"
I already do that. I copied assembly contracts in the C:\ClassLibrary1Folder\. I also try to put assembly contracts in C:\ClassLibrary1Folder\CodeContracts subfolder but nothing work.I think it's bug, because if you look the generated code in ConsoleApplication1 :
A wrapper method is created for the Display method (V$Display), but not for the Class1 constructor call...
Best regards,
Gilles TOURREAU - MVP C#
Architecte logiciel/Consultant/Formateur Freelance
Blog : http://gilles.tourreau.fr
- MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
- MCITP : SQL Server 2008 Developper
- MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0- Ditandai sebagai Jawaban oleh Gilles TOURREAUMVP 12 Juni 2012 11:26
- Tanda sebagai Jawaban dihapus oleh Gilles TOURREAUMVP 12 Juni 2012 11:26
-
07 Juni 2012 21:34Pemilik
Sorry! I totally mis-read your entire post. I just went back and looked at it carefully and now realize that you were talking about the *constructor* (yes, I realize now that you did say that!) and not the second line in Main. I had thought you were saying that the wrapper method was being called, but wasn't implemented.
Okay, now that I am awake --- unfortunately, as stated in Section 6.2.4 of the documentation, we do not currently support call-site requires on constructors. I am looking into why we have that restriction, but at least you know it is a feature, not a bug!
Mike Barnett
- Disarankan sebagai Jawaban oleh Mike BarnettMicrosoft Employee, Owner 07 Juni 2012 21:34
- Ditandai sebagai Jawaban oleh Gilles TOURREAUMVP 12 Juni 2012 11:26
-
08 Juni 2012 11:50
Hello,
Thanks Mike for your investigations.
Tell the Microsoft community if Microsoft consider to support this scenario.Best regards,
Gilles TOURREAU - MVP C#
Architecte logiciel/Consultant/Formateur Freelance
Blog : http://gilles.tourreau.fr
- MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
- MCITP : SQL Server 2008 Developper
- MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 -
11 Juni 2012 20:21Pemilik
We are trying to move all of the tools on top of a different infrastructure. As part of that I am putting all new features into the new code and not the old code. So I've already fixed this in the new code: it now handles call-site requires on constructors. Unfortunately, I do not yet have a release date for the new tools. But I am very hopeful it will be quite soon.Mike Barnett
- Ditandai sebagai Jawaban oleh Gilles TOURREAUMVP 12 Juni 2012 11:26