使用Contract.Assert(true)时该怎么办,方法必须返回一些东西?

dev*_*ium 5 c# design-by-contract .net-4.0 code-contracts

我有一些代码与以下逻辑:

//pseudo-code
foreach (element in elementList) {
    if (element is whatever)
        return element;
    }
}
Run Code Online (Sandbox Code Playgroud)

理论上,总有一个元素是什么,所以这个方法应该没有问题.在任何情况下,我都在方法的最后确定了一个断言,以确保:

//pseudo-code
foreach (element in elementList) {
    if (element is whatever)
        return element;
    }
}

Contract.Assert(false, "Invalid state!");
Run Code Online (Sandbox Code Playgroud)

问题是因为这个方法必须返回一些东西,并且编译器不理解断言会破坏程序执行.在使用Contracts之前,在这种情况下,我曾经抛出一个Exception,它解决了这个问题.你会如何处理Contract.Assert()?在Contract.Assert()调用之后返回null或default(element_type),知道它永远不会被调用并关闭编译器吗?或者还有其他更优雅的方式吗?

谢谢

Mik*_*Two 2

你可以去

var result = null;
foreach (element in elementList) {
    if (element is whatever)
        result = element;
        break;
    }
}

Contract.Assert(result != null, "Invalid state!");
return result;
Run Code Online (Sandbox Code Playgroud)

它引入了一个中断,但返回周围看起来确实更干净。

甚至更清洁

return elementList.Where( e => e is whatever).First();
Run Code Online (Sandbox Code Playgroud)

编辑 @devoured 指出上面的内容将覆盖整个列表

更干净,无处可去

return elementList.First( e => e is whatever);
Run Code Online (Sandbox Code Playgroud)

结束编辑

如果什么也没找到,那就爆炸了。

但如果你真的想要断言它可能是

var results = elementList.Where( e => e is whatever);
Contract.Assert(results.Count() == 1, "Boo");
return results.First();
Run Code Online (Sandbox Code Playgroud)

但这也会迭代整个列表。