我一直在玩VS2008上的Code Contracts(http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx).
它们肯定很好,并为方法中的if-then-throw检查提供了一个可靠的替代方案.
尽管如此,我一直希望他们能够满足我对非可空引用类型的强烈感受.
唉,从我所看到的情况来看似乎并非如此.
这就是我的理解:
这样的事情仍会在运行时引起问题:
MyClass a = null;
a.ToString();
我仍然必须明确地写支票,即使是以更简洁和简化的方式.
除非您使用VS Team System,否则您只能使用代码契约在运行时检查事物,在编译时没有任何好处.
这意味着当出现问题时你仍然需要处理事情.
与处理简单异常没什么不同.
即使使用VSTS,静态分析也不如在运行时完成的那样好.
这是完全可以理解的,但这仍然是该功能用于运行时使用的另一个标志.
如果我错了,请纠正我,但从我看到的情况来看,Code Contracts无法使我的生活变得更轻松,而且我的程序更加健壮,就像非可空引用类型一样.
不要误会我的意思,我不喜欢代码合同.
它们是整个框架的一个非常好的增强.
只是如果这没有填补C#通过没有非可空引用类型而离开的空白,此时我担心什么都不会.
你怎么看?
晚上好,
我刚开始玩Microsoft.Contracts(最新版本)并将其插入到示例界面之上,现在它看起来像这样:
namespace iRMA2.Core.Interfaces
{
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics.Contracts;
/// <summary>
/// Base Interface declarations for iRMA2 Extensions
/// </summary>
[InheritedExport]
[ContractClass(typeof(IiRMA2ExtensionContract))]
public interface IiRMA2Extension
{
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name of the Extension.</value>
string Name { get; }
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
string Description { get; }
/// <summary>
/// Gets the author of the extension. Please provide complete information to get …Run Code Online (Sandbox Code Playgroud) 我打算使用新的.NET 4 Code Contracts功能进行未来的开发.这让我想知道我们是否必须Contract.Requires(...)在一系列方法中冗余地指定等效语句.
我认为一个代码示例胜过千言万语:
public bool CrushGodzilla(string weapon, int velocity)
{
Contract.Requires(weapon != null);
// long code
return false;
}
public bool CrushGodzilla(string weapon)
{
Contract.Requires(weapon != null); // specify contract requirement here
// as well???
return this.CrushGodzilla(weapon, int.MaxValue);
}
Run Code Online (Sandbox Code Playgroud)
对于运行时检查它并不重要,因为我们最终总是会遇到需求检查,如果失败我们会收到错误.
但是,当我们再次在第二次超载中没有指定合同要求时,它被认为是不好的做法吗?
此外,还将具有编译时检查的功能,并且还可能设计代码合同的时间检查.在Visual Studio 2010中,它似乎尚不适用于C#,但我认为有一些类似Spec#的语言已经可以使用.当我们编写代码来调用这样的方法时,这些引擎可能会给我们提示,而我们的参数目前可以或将会是null.
所以我想知道这些引擎是否总是会分析一个调用堆栈,直到找到一个目前不满意的合同方法?
此外,在这里我了解到的区别Contract.Requires(...)和Contract.Assume(...).我想在这个问题的背景下还要考虑差异呢?
我一直在研究.NET 4.0代码契约,并查看stackoverflow以及有关此问题.
我仍然没有遇到任何使用代码契约的示例代码,这让我感到疑惑..这真的很有用吗?或者也许它唯一有用的一个代码达到一定的复杂性?那里有人使用代码合同,他们真的很高兴吗?
在我看来,所有的代码契约都是一个断言在发生什么,什么出去与加入能够揣摩的值在编译时进出的方法......但随后这是怎么回事在你的所有方法上需要更多的代码..值得吗?
我注意到一个好处是,在我看来,你可以使用代码的合同类型的单元测试的第一线......然后,当你写单元测试,可以避免写一些比较基本的测试,因为代码契约覆盖它了. . 真的吗 ?
合同是否适用于WCF调用?我猜不是因为代理是自动创建的,你不能改变.
在编译使用代码契约的代码时,我有一个非常奇怪的错误,我不明白.
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == default(Guid));
}
Run Code Online (Sandbox Code Playgroud)
失败,出现以下错误:
合同格式错误.在方法'<ProjectName> .ObjectInvariant'中赋值后找到不变量.
如果代码修改如下:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == Guid.Empty);
// Noticed the Guid.Empty instead of default(Guid)?
}
Run Code Online (Sandbox Code Playgroud)
它汇编得很好.
我有什么问题default(Guid)?
假设我有一个自定义集合类,它提供了一些内部线程同步.例如,简化的Add方法可能如下所示:
public void Add(T item)
{
_lock.EnterWriteLock();
try
{
_items.Add(item);
}
finally
{
_lock.ExitWriteLock();
}
}
Run Code Online (Sandbox Code Playgroud)
最新的Code Contracts抱怨说CodeContracts: ensures unproven: this.Count >= Contract.OldValue(this.Count).问题是这真的无法证明.我可以确保在内部锁定内,Count将大于其先前的值.但是,在方法的退出处,我无法确保这一点.退出锁之后,在方法完成之前,另一个线程可以发出两个Removes(可能是不同的元素),使合同无效.
这里的基本问题是,只有在整个应用程序中一致地使用锁定以对集合进行所有访问时,才能认为集合合同在特定锁定上下文中是有效的.我的集合必须在多个线程中使用(非冲突的Add和Remove是一个有效的用例),但我仍然希望实现ICollection<T>.即使我知道我不能,我是否应该假装我能够满足这个确保要求的假设?令我印象深刻的是,BCL系列中没有一个能够真正确保这一点.
编辑:
基于一些进一步的调查,听起来最大的问题是合同重写者可能引入不正确的断言,导致运行时失败.基于此,我认为我唯一的选择是限制我的接口实现IEnumerable<T>,因为合同ICollection<T>暗示实现类不能提供内部线程同步(访问必须始终在外部同步.)这对我的特定情况是可接受的(所有客户端)希望改变集合直接了解类类型,但我很想知道是否有其他解决方案.
我是REST的新手,听起来应该很简单.在.NET应用程序中,我可以创建对WCF服务的引用,并为我生成所有可用类型的合同.
现在我正在尝试在Windows Phone 7应用程序中使用REST服务.虽然我可以进行调用并获得正确的响应,但是有一种简单的方法来创建每个对象将被反序列化的类吗?
我正在使用RestSharp来管理我的呼叫.在我看到的一些例子中,用户已经创建了自己的类,并手动生成了xml.如果可能的话,我想避免这种情况.
非常感谢!
这是使用Visual Studio 2012的ReSharper 7.下面的示例
// This code works fine and as expected and ReShrper is happy with it
if (!string.IsNullOrWhiteSpace(extension) && extension.Length == 3)
{
// do something
}
// ReSharper highlights "extension" in extension.Length with "Possible 'System.NullReferenceException'"
if (!extension.IsNullOrWhiteSpace() && extension.Length == 3)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
并且,我创建了以下扩展方法:
public static class StringExtensions
{
public static bool IsNullOrWhiteSpace(this string s)
{
return string.IsNullOrWhiteSpace(s);
}
}
Run Code Online (Sandbox Code Playgroud)
我查看了反映的代码,String.IsNullOrWhiteSpace它没有任何相关的代码或属性,这些代码或属性会突出显示R#验证检查.这是硬编码在R#?
我查看了代码合同,但我不确定它会对我的情况有所帮助.
您是否有一种解决方法可以向ReSharper证明我的扩展方法已经验证了检查条件?
c# resharper extension-methods code-contracts nullreferenceexception
假设以下代码:
[ContractClass(typeof(ICC4Contract))]
public interface ICC4
{
bool IsFooSet { get; }
string Foo { get; }
}
public class CC4 : ICC4
{
private string _foo;
public bool IsFooSet { get { return Foo != null; } }
public string Foo { get { return _foo; } }
}
[ContractClassFor(typeof(ICC4))]
public abstract class ICC4Contract : ICC4
{
public bool IsFooSet
{
get
{
Contract.Ensures((Contract.Result<bool>() && Foo != null)
|| !Contract.Result<bool>());
return false;
}
}
public string Foo
{
get
{ …Run Code Online (Sandbox Code Playgroud) 我正在用C#编写ReSharper 8.0和VS2012 for .Net 4.0.
ReSharper包含一个属性:JetBrains.Annotations.PureAttribute.这用于提供检查"不使用纯方法的返回值".
代码约定包括一个属性:System.Diagnostics.Contracts.PureAttribute.代码合同检查使用它来确保调用不会产生可见的状态更改,因此不需要重新检查对象的状态.
目前,为了获得这两种工具的功能,需要使用每个属性的方法对方法进行注释.更糟糕的是,因为它们都共享相同的类型名称,所以您需要限定每个属性.
[Pure]
[Jetbrains.Annotations.Pure]
public bool isFinished() {
...
Run Code Online (Sandbox Code Playgroud)
为避免这种情况,应该有三种方法:
这些都有可能吗?