.net 在调用例程之后和之前,在哪里计算不变量?

.net 在调用例程之后和之前,在哪里计算不变量?,.net,code-contracts,invariants,eiffel,.net,Code Contracts,Invariants,Eiffel,在契约式设计中,类不变量必须在两种情况下满足:创建对象后和调用例程后。是否有任何示例或条件,我也必须在调用例程之前进行计算?在调用功能之前,可能会违反类不变量。情况可能不同,我只介绍最明显的情况: 别名。对象引用类不变量中涉及的其他对象,并且该其他对象由第三方修改: class SWITCH -- Creation procedure is ommitted for brevity. feature toggle1, toggle2: TOGGLE -- Mutually exclusi

在契约式设计中,类不变量必须在两种情况下满足:创建对象后和调用例程后。是否有任何示例或条件,我也必须在调用例程之前进行计算?

在调用功能之前,可能会违反类不变量。情况可能不同,我只介绍最明显的情况:

  • 别名。对象引用类不变量中涉及的其他对象,并且该其他对象由第三方修改:

    class SWITCH -- Creation procedure is ommitted for brevity.
    feature
        toggle1, toggle2: TOGGLE -- Mutually exclusive toggles.
        ...
    invariant
        toggle1.is_on = not toggle2.is_on
    end
    
    现在,以下代码违反了类
    开关的不变量

    switch.toggle1.turn_on -- Make `switch.toggle1.is_on = True`
    switch.toggle2.turn_on -- Make `switch.toggle2.is_on = True`
    switch.operate -- Class invariant is violated before this call
    
  • 外部状态。对象与类不变量中引用的外部数据耦合,可能会意外更改:

    class TABLE_CELL feature
        item: DATA
            do
                Result := cache -- Attempt to use cached value.
                if not attached Result then
                        -- Load data from the database (slow).
                    Result := database.load_item (...)
                    cache := Result
                end
            end
    feature {NONE} -- Storage
        cache: detachable DATA
    invariant
        consistent_cache: -- Cache contains up-to-date value.
            attached cache as value implies
            value ~ database.load_item (...)
    end
    
    现在,如果在应用程序外部修改数据库,缓存可能会变得不一致,并且在以下功能调用之前会触发类不变冲突:

    data := table_cell.item -- Class invariant is violated before this call.
    
  • 回拨。一个对象可以在无效状态下传递给另一个对象:

    class HANDLER feature
        process (s: STRUCTURE)
            do
                ... -- Some code that sets `is_valid` to False.
                s.iterate_over_elements (Current)
            end
        process_element (e: ELEMENT)
            do
                ...
            end
        is_valid: BOOLEAN
            do
                ...
            end
    invariant
        is_valid
    end
    
    由类
    结构
    的功能
    迭代元素
    执行的对
    HADNLER
    的回调会导致不变冲突,因为
    处理程序
    状态不好:

    handler.process_element (...) -- Class invariant is violated before the call.
    
  • 有人可能会争辩说,所有这些情况都是由于软件错误和缺陷造成的,但这正是类不变量捕捉这些情况的目的,包括在特性调用之前发生冲突的情况