即使Runtime Checking = true,汇编也不会被ccrewriter重写

时间:2016-01-10 17:47:39

标签: .net visual-studio code-contracts

我有一个项目。在这个项目中,我使用.NET的代码契约。我设置Runtime Checking = true。 。但是在运行时我有一个ContractException:

  

抛出异常:' System.Diagnostics.Contracts.ContractException'在   mscorlib.dll中

     

附加信息:装配(可能是" Common")必须是   使用代码合同重写二进制重写器(CCRewrite)因为   它调用Contract.Ensures和CONTRACTS_FULL符号   定义。删除CONTRACTS_FULL符号的任何显式定义   从您的项目和重建。 CCRewrite可以从中下载   http://go.microsoft.com/fwlink/?LinkID=169180

     

安装重写器后,可以在Visual Studio中启用它   从“代码约定”窗格上的项目“属性”页面中。确保   "执行运行时合同检查"已启用,将定义   CONTRACTS_FULL   异常的原因不是这个条件不能实现,而是组件不会被重写。安装了Ccrewriter,我没有遇到其他项目的麻烦。

发生的代码:

Contract.Ensures(_instance != null && _instance._authData != null);

此代码不会被重写,因此会在程序开始时执行。

我知道只有使用postbuild事件才能执行ccrewrite,但我想避免使用它。

这种行为可能是什么原因?如何检查是否调用了ccrewrite?我在构建输出中没有看到任何信息。

1 个答案:

答案 0 :(得分:1)

看起来它是CC中的一个错误。我找到了一个奇怪的工作区:

我的项目的Csproj文件之前是用手编辑的,所以它有一个带有signAssebly标签和codecontracts设置的部分:

import processing.video.*; 
boolean valid=false; 
String[] one = {  

"1.mp4", "2.mp4", "3.mov", "4.mov", "5.mov", "6.mov",   "7.mov",
"8.mov", "9.mov" };

 Movie myMovie;    

 int a = 0; 
 float md = 0; 
 float mt = 0;   

 void setup() {   
 size(400, 400, P2D); 
 }

 void draw() 
 {   
   if (valid){
    image(myMovie, 0, 0, width, height);   
    }   
 }   

 void keyPressed() 
 {
 if (key == 'a' || key == 'A')  
   {
    valid=true;
    myMovie = new Movie(this, ""+int(random(1, 3)));
    myMovie.play();   }
 else if (key == 's' || key == 'S')   
 {
   valid=true;
   myMovie = new Movie(this, ""+int(random(4, 6)));
   myMovie.play();   }
 else if (key == 'd' || key == 'D')   
 {
   valid=true;
   myMovie = new Movie(this, ""+int(random(7, 9)));
   myMovie.play();   }
 else   
 {
    myMovie.stop();   } 

所以我将CodeContracts设置移动到通常存储它的部分;

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <SignAssembly>false</SignAssembly>
  <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
  <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
  <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>

  ....

  <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
  <CodeContractsReferenceAssembly>DoNotBuild</CodeContractsReferenceAssembly>
  <CodeContractsAnalysisWarningLevel>3</CodeContractsAnalysisWarningLevel>
  <RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>

现在它有效。我认为放置部分没有什么大的区别,它只对构建目标很重要。

如果有人可以解释,为什么会发生,我会重新接受答案。