如何将函数设为私有方法?

Ter*_*ryP 4 c# lambda encapsulation anonymous-function

我正在研究一种需要在不同位置重复一个小操作的方法,但要重复的代码应该是该方法的私有代码.显而易见的解决方案是嵌套函数.无论我尝试什么,C#编译器对我来说都是barfs.

大致等于这个Perl片段的东西:

my $method = sub {
    $helper_func = sub { code to encapsulate };

    # more code

    &$helper( called whenever needed );

    # more code
}
Run Code Online (Sandbox Code Playgroud)

正是我在谈论的,以及我在C#中想要实现的目标.

类中没有其他方法应该能够在此上下文中访问辅助函数.在C#中编写这个构造的最合理的方法,就像在我看来会是这样的:

var helper = (/* parameter names */) => { /* code to encapsulate */ };
Run Code Online (Sandbox Code Playgroud)

实际上让编译器获得了保持.

由于这样的赋值是被禁止的,因为使用较旧的delegate(){}语法代替lambda,因此在方法中声明一个委托类型 - 然而csc实际上允许我写的是,这是:

private delegate /* return type */ Helper(/* parameters */);
private /* return type */ method(/* parameters */) {

    Helper helper = (/* parameter names */) => { 
        /* code to encapsulate */
    };

    // more code

    helper( /* called whenever needed */ );

    // more code
}
Run Code Online (Sandbox Code Playgroud)

对于不复制和粘贴一大堆代码并手动编辑参数这一切都很好,但是它会将私有委托类型泄漏给类的其余部分而不是将其保密.这首先打败了目的.对参数使用goto语句和局部变量可以在此上下文中更好地封装"helper",而不会牺牲代码重用.如果我想通过寄存器传递参数来模拟函数调用,我想宁愿使用汇编程序.我没有找到一种可接受的重构代码的方法来完全避免这个问题.

那么,甚至可以强制这种面向公共对象的语言服从吗?

Las*_*ert 8

你实际上可以在C#中做到这一点.

Func<T1, T2, ..., TReturn> myFunc = (a, b, ...) =>
{
  //code that return type TReturn
};
Run Code Online (Sandbox Code Playgroud)


如果需要匿名方法返回类型void使用Action而不是Func:

Action<T1, T2, ...> myAction = (a, b, ...) =>
{
  //code that doesn't return anything
};
Run Code Online (Sandbox Code Playgroud)


Sco*_*ein 6

如果你在C#3.5或更高版本,你可以利用lambdas和便利委托声明Func<>Action<>.所以举个例子

void DoSomething()
{
  Func<int,int> addOne = (ii) => ii +1;
  var two = addOne(1);
}
Run Code Online (Sandbox Code Playgroud)

不能做的原因

var addOne = (ii) => ii +1;
Run Code Online (Sandbox Code Playgroud)

因为Homoiconicity,lambda可以被解释为两个不同的结构,一个委托和一个表达式树.因此需要在声明中明确.