代码合约、forall 和自定义可枚举
我正在使用 C# 4.0 和代码合约,并且有自己的自定义 GameRoomCollection : IEnumerable
。
我想确保 GameRoomCollection
的任何实例都不会包含 null
值元素。不过,我似乎无法做到这一点。我没有制定一般规则,而是尝试做一个简单明了的例子。 AllGameRooms
是 GameRoomCollection
的实例。
private void SetupListeners(GameRoom newGameRoom) {
Contract.Requires(newGameRoom != null);
//...
}
private void SetupListeners(Model model) {
Contract.Requires(model != null);
Contract.Requires(model.AllGameRooms != null);
Contract.Assume(Contract.ForAll(model.AllGameRooms, g => g != null));
foreach (GameRoom gameRoom in model.AllGameRooms)
SetupListeners(gameRoom);//<= Warning: Code Contracts: Requires unproven: newGameRoom != null
}
谁能看出为什么我没有证明 gameRoom
不是 null
?
编辑:
在迭代之前添加对象的引用也不起作用:
IEnumerable<IGameRoom> gameRooms = model.AllGameRooms;
Contract.Assume(Contract.ForAll(gameRooms, g => g != null));
foreach (IGameRoom gameRoom in gameRooms)
SetupListeners(gameRoom);//<= Warning: Code Contracts: Requires unproven: newGameRoom != null
编辑2:
但是:如果我将游戏室集合类型转换为数组,它可以正常工作:
IGameRoom[] gameRoomArray = model.AllGameRooms.ToArray();
Contract.Assume(Contract.ForAll(gameRoomArray, g => g != null));
foreach (IGameRoom gameRoom in gameRoomArray)
SetupListeners(gameRoom);//<= NO WARNING
是这是因为您无法为 IEnumerable
接口的方法定义规则?
编辑3:问题是否与这个问题?
I am using C# 4.0 and Code Contracts and I have my own custom GameRoomCollection : IEnumerable<GameRoom>
.
I want to ensure, that no instances of GameRoomCollection
will ever contain a null
value element. I don't seem to be able to this, though. Instead of making a general rule, I have tried to do a plain and simple example. The AllGameRooms
is an instance of GameRoomCollection
.
private void SetupListeners(GameRoom newGameRoom) {
Contract.Requires(newGameRoom != null);
//...
}
private void SetupListeners(Model model) {
Contract.Requires(model != null);
Contract.Requires(model.AllGameRooms != null);
Contract.Assume(Contract.ForAll(model.AllGameRooms, g => g != null));
foreach (GameRoom gameRoom in model.AllGameRooms)
SetupListeners(gameRoom);//<= Warning: Code Contracts: Requires unproven: newGameRoom != null
}
Can anyone see, why I haven't proven, that gameRoom
is not null
?
EDIT:
Adding a reference for the object before iterating does not work either:
IEnumerable<IGameRoom> gameRooms = model.AllGameRooms;
Contract.Assume(Contract.ForAll(gameRooms, g => g != null));
foreach (IGameRoom gameRoom in gameRooms)
SetupListeners(gameRoom);//<= Warning: Code Contracts: Requires unproven: newGameRoom != null
EDIT2:
However: If I convert the game room collection type to an array, it works fine:
IGameRoom[] gameRoomArray = model.AllGameRooms.ToArray();
Contract.Assume(Contract.ForAll(gameRoomArray, g => g != null));
foreach (IGameRoom gameRoom in gameRoomArray)
SetupListeners(gameRoom);//<= NO WARNING
Is this caused by the fact, that you cannot define a rule for methods of the IEnumerable<T>
interface?
EDIT3: Can the problem somehow be related to this question?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这可能与 GetEnumerator 方法的纯度有关。 PureAttribute
合约仅接受定义为的方法[纯](无副作用)。
一些额外信息代码契约,寻找纯度
引用:
I think this might have to do with purity of the GetEnumerator method. PureAttribute
Contracts only accept methods that are defined as [Pure] (side effect free).
Some extra information Code Contracts, look for purity
Qoute:
我怀疑这是因为
model.AllGameRooms
返回一个IEnumerable
,它在每个属性访问上可能不同。尝试使用:
I suspect it's because
model.AllGameRooms
returns anIEnumerable<GameRoom>
which could be different on each property access.Try using: