首页 > 解决方案 > 如何检查函数在运行时是否没有副作用(纯)?

问题描述

假设我们已经加载了一个函数,该函数F接受/输出一组args并返回一个result. 如果这对成员和函数F以外的任何东西没有作用,如何在运行时检查?args意思是 no Console.Writeline, Singletons (或其他未在 中出现的东西args)。CodeContracts图书馆或其他解决方案有可能吗?

假设我们知道该[Pure]属性出现在函数定义中。当我们有一个lambda时,这在很多情况下都很糟糕,但至少它会是一些东西

为什么我看不到如何[Pure]提供帮助 - 此代码编译:

class Test {
    public struct Message {
        public string Data;
    }

    public struct Package {
        public int Size;
    }

    [Pure]
    public static List<Package> Decomposse(Message m) {
        Console.WriteLine("rrrr"); // This sould not happen
        var mtu = 1400;
        Package p = new Package{Size = mtu};
        return Enumerable.Repeat(p, m.Data.Length / mtu).ToList();
    }
}

而且我想消除(或至少检测到该函数调用类似的东西Console.WriteLine("rrrr")

标签: c#.netreflectionside-effects

解决方案


函数是否有输入或结果并不重要。代码体中可能会发生太多事情,例如实例化的对象构造函数。问题是现代语言。

仅检索 DateTime.Now() 之类的数据的安全 API 调用又如何呢?您是否要为您组织中或地球上的所有应用程序构建一个改变状态并随着时间的推移为我们其他人保持更新的 API 调用列表?您是否要记录编译器内联的处理过程?那么通过将这种方法简化为荒谬,我们是否可以接受它不可行?

我的架构模型机器应该只改变“产品”数据点,但即使我承认这是一个不可执行的规则。我还有其他规则来尝试强制执行确定性。但是,这些模块必须在某些时候调用 API 才能完成今天已经在 API 中组织的有意义的工作。否则我们将全部重写。

    class Machine1Product
    {
        public Cvar<int> Y { get; set; }
    }
    class Machine1 : Producer<Machine1Product>, IMachine
    {
        public Cvar<int> X { get; set; }
        public void M()
        {
            // work which changes only product data points (Y)
        }
    }

在为函数开发出极简语言之前,没有观察或预防副作用。


推荐阅读