首页 > 解决方案 > 函数参数 VS 私有引用

问题描述

我尝试通过https://stackoverflow.com/search?q=parameters+vs+private+reference在这里搜索

我的编码开始与此类似(我从验证中删除了很多其他代码以尝试..catch 只是为了保持查看的代码简单),我将数据表传递给函数:

Private Function get_value_from_datatable(dt As DataTable, condition As String, column_value_to_return As String) As String
    Dim return_value As String = ""
    If dt IsNot Nothing Then
        Dim drs() As DataRow
        drs = dt.Select(condition)
        If drs.Count = 1 Then
            return_value = drs(0)(column_value_to_return)
        End If
    End If
    get_value_from_datatable = return_value
End Function

经过一番阅读,我发现自己想知道这是否更好/更快/更受欢迎,因为我目前只有一个数据表:

Private priv_datatable As DataTable ' Which gets set somewhere in the code before the ff function is called.'
Private Function get_value_from_datatable(condition As String, column_value_to_return As String) As String
    Dim return_value As String = ""
    If priv_datatable IsNot Nothing Then
        Dim drs() As DataRow
        drs = priv_datatable.Select(condition)
        If drs.Count = 1 Then
            return_value = drs(0)(column_value_to_return)
        End If
    End If
    get_value_from_datatable = return_value
End Function

只是我想做最佳实践并理解为什么一个可能比另一个更受欢迎。我还想到,将来我可能会访问多个数据表,但我不知道这是否会很快或几个月后发生。

标签: .net

解决方案


一个大多数程序员都没有意识到的深层次问题。我的架构禁止参数。

参数代表消费者的“即时控制”。换句话说,消费者必须手动控制功能(带参数)来操作它。即时控制是微观管理者的最爱,因为他们不关心有条理。

函数所依赖的属性代表“连续控制”。消费者可以在选择的任何时间在触发之前配置该功能。执行不需要一次手动交付所有数据。当您这样做了几次后,您将不会返回参数。

通过将控制变量建模为我所说的“参考属性”,协作(制造)过程更进一步。

   public Cvar<int> X { get; set; }

进程中的模块可以绑定到相同的变量,从而在进程中更改任何其他模块的配置,这显然优于通过传递参数分配文字值的直接控制。因此,一个过程由模块组成,这些模块与数据点交互而不是彼此交互。这些模块只包含一个函数——下面的 M(),其余的结构包含输入和输出。

    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
        }
    }

进程本身只包含模块,除了分配内存(在下面的 D() 中)和绑定(在下面的 O() 中)数据点之外什么都不做。这记录了流程的数据供应链。

    // the process's DTO or finished product
    class MyProduct
    {
        public Cvar<int> X { get; set; }  // a reference to an int variable
        public Cvar<int> Y { get; set; }
        public Cvar<int> Z { get; set; }
    }
    class Process1 : Producer<MyProduct>, IProcess, IMachine
    {
        public Machine1 One { get; set; }
        public Machine2 Two { get; set; }

        // instantiates all machines and product properties 
        public void D() { ... }

        // binds each machine to interact with the product of this process
        public void O()
        {
            One.X = Product.X;            // the machine consumes X
            One.Product.Y = Product.Y;    // the machine changes Y

            Two.Y = Product.Y;            // the machine consumes Y
            Two.Product.Z = Product.Z;    // the machine changes Z
        }

        // observable, controllable and communication-free execution
        public void M()
        {
            One.M();
            Two.M();
        }
    }

整合与绑定

http://www.powersemantics.com/o.html

从技术上讲,参数意味着数据被复制到被调用函数的堆栈帧,如果数据最初在堆栈中,这对性能友好。但是,如果数据最初位于堆上,则调用者必须获取它并导致缓存未命中。简而言之,被调用的方法从堆本身中获取它没有区别。我不能说同一进程中不同模块的后续提取是否会导致额外的缓存未命中。

对象字段和属性位于堆上。只有函数内的本地值类型数据值在堆栈上。这是要解释的另一件大事。https://jonskeet.uk/csharp/memory.html

最后,请注意消费者不应该从传入的内容中提取数据,就像在您的示例代码中一样。这就是单独的“提取器”模块的原因。将生产者与消费者分开,使功能体不受场地特异性的影响。

提取直到实现控制


推荐阅读