我正在阅读代码契约,乍一看似乎是相当革命性的,但我似乎无法让它们发挥作用.我正在运行Windows 8和Visual Studio 2012 Premium(两者的发行版本).然后,我通过单击"下载代码合同"链接从此处安装了代码合同.
然后我在一个全新的控制台应用程序中编写了以下代码:
class Program
{
static void Main(string[] args)
{
var answer = Add(0, 5);
Console.Write(answer);
Console.ReadLine();
}
static int Add(int x, int y)
{
Contract.Requires(x > 0 && y > 0);
return x + y;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望编译失败,因为第一个参数Add是0,但程序成功并打印出5到控制台.
我已尝试使用默认的代码合约设置,并且还使用了一些东西而无济于事.我目前的设置如下:

我有什么想法我做错了吗?
更新:
这是Build窗口的结果.看起来它正在做某事,但只是提出警告而不是错误.在我观看的视频中,这些内容被标记为编译错误,程序甚至无法运行.
1>------ Build started: Project: DeleteMe, Configuration: Debug Any CPU ------
1> DeleteMe -> c:\users\mike\documents\visual studio 2012\Projects\DeleteMe\DeleteMe\bin\Debug\DeleteMe.exe
1> CodeContracts: Task manager is unavailable.
1> CodeContracts: DeleteMe: Run static contract analysis. …Run Code Online (Sandbox Code Playgroud) 我正在经历一个关于SO的问题,这是关于c#4.0的新功能和jon双向飞碟的答案有C#4.0的Code Contracts功能..但我真的不明白何时使用它们..任何建议......
就我在一本简单的书中所读到的,代码契约可能会降低运行时性能.
是否可以在生产中禁用代码合同?
我开始使用代码合同,虽然Contract.Requires非常简单,但我很难看到Ensures实际上做了什么.
我试过创建一个这样的简单方法:
static void Main()
{
DoSomething();
}
private static void DoSomething()
{
Contract.Ensures(false, "wrong");
Console.WriteLine("Something");
}
Run Code Online (Sandbox Code Playgroud)
我从来没有看到消息"错误",也没有抛出异常或其他任何东西.
那它实际上做了什么?
我希望以最优雅的方式验证我的代码中的方法参数.代码合同似乎在2015年不起作用.有没有人使用任何替代方案?
我最近阅读了一篇文章,将"按合同设计"与"测试驱动开发"进行了比较.似乎有很多重叠,一些冗余,以及DbC和TDD之间的一点协同作用.例如,有一些系统可以根据合同自动生成测试.
DbC以什么方式与现代类型系统重叠(例如在haskell中,或者是那些依赖类型的语言之一)并且有两点使用两者都比哪一方更好?
haskell types type-systems design-by-contract code-contracts
以下简单代码将通过Code Contracts的静态检查器产生"不变的未经证实"警告,尽管_foo无法做到null.警告是针对return内部声明的UncalledMethod.
public class Node
{
public Node(string s1, string s2, string s3, string s4, object o,
string s5)
{
}
}
public class Bar
{
private readonly string _foo;
public Bar()
{
_foo = "foo";
}
private object UncalledMethod()
{
return new Node(string.Empty, string.Empty, string.Empty, string.Empty,
GetNode(), string.Empty);
}
private Node GetNode()
{
return null;
}
public string Foo
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return _foo;
}
}
[ContractInvariantMethod]
private …Run Code Online (Sandbox Code Playgroud) 我正在阅读Jon Skeet目前正在阅读的"C#深度",并且有一个示例描述代码契约,其中一个抽象类实现了一个接口,该接口具有作为接口的附带类,代码合同的术语:'Contract Class For'(我不会在这里详细介绍代码合同的运作方式.
界面(第467页):
[ContractClass(typeof(ICaseConverterContracts))]
public interface ICaseConverter
{
string Convert(string text);
}
Run Code Online (Sandbox Code Playgroud)
抽象类:
[ContractClassFor(typeof(ICaseConverter))]
internal abstract class ICaseConverterContracts : ICaseConverter
{
public string Convert(string text)
{
Contract.Requires(text != null);
Contract.Ensures(Contract.Result<string>() != null);
return default(string); // returns dummy value
}
// prevents instantiation
private ICaseConverterContracts() { }
}
Run Code Online (Sandbox Code Playgroud)
(我根据书中的评论在代码中添加了注释)
我的问题:
当你无法实例化一个抽象类时,为什么有必要将私有构造函数添加到这个抽象类?我得不到什么?
这是我的代码:
public class RegularPolygon
{
public int VertexCount;
public double SideLength;
public RegularPolygon(int vertexCount, double sideLength)
{
Contract.Requires(vertexCount >= 3);
VertexCount = vertexCount;
SideLength = sideLength;
}
[ContractInvariantMethod]
private void RegularPolygonInvariants()
{
Contract.Invariant(VertexCount>=3);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用Contract.Requires和Contract.Invariant方法来防止vertexCount变量小于或等于2; 但是我仍然能够初始化一个具有2个或更少边的RegularPolygon.我的(简化)NUnit测试如下所示:
[TestFixture]
class TestRegularPolygon
{
private RegularPolygon _polygon;
[SetUp]
public void Init()
{
_polygon = new RegularPolygon(1, 50);
}
[Test]
public void Constructor()
{
Assert.That(_polygon.VertexCount,Is.GreaterThanOrEqualTo(3));
}
}
Run Code Online (Sandbox Code Playgroud)
以上测试也通过,我无法弄清楚为什么!
起初我以为ReSharper可能会弄乱一些东西,因为它会在我尝试使用Contract命名空间中的方法时显示该行并显示此消息:
跳过方法调用.编译器不会生成方法调用,因为该方法是有条件的,或者是没有实现的部分方法.
但暂停R#并在NUnit中运行测试具有相同的结果,VS中也没有错误或警告.所以我认为这只是因为ReSharper还没有强调代码合同的兼容性.
我查看了文档,据我所知,我不应该遇到这个问题.
我是否正确使用代码合同或是我的环境阻止它以某种方式工作?
谢谢.
c# resharper design-by-contract visual-studio-2010 code-contracts
将后置条件添加到返回的异步方法的推荐方法是什么Task<T>?
我已经阅读了以下建议:
http://social.msdn.microsoft.com/Forums/hu-HU/async/thread/52fc521c-473e-4bb2-a666-6c97a4dd3a39
帖子建议将每个方法实现为同步,签约,然后将异步对应实现为简单的包装器.不幸的是,我不认为这是一个可行的解决方案(也许是通过我自己的误解):
await其他异步方法的新方法因此被强制为异步.这些方法本质上是异步的,不能轻易转换为同步.它们不仅仅是包装纸.即使我们通过说我们可以使用.Result或.Wait()代替await(这实际上会导致某些SyncContexts死锁,并且无论如何都必须在异步方法中重写)来使后一点无效,我仍然相信第一点.
有没有其他想法,或者有什么我错过的代码合同和TPL?
code-contracts ×10
c# ×8
.net ×3
async-ctp ×1
c#-4.0 ×1
haskell ×1
production ×1
resharper ×1
type-systems ×1
types ×1