嵌套方法?它们为什么有用?

Bob*_*lan 12 c# python

所以我只是在C#和Python中学习一些新东西.结果证明两种语言都支持嵌套方法(C#sort of do).

蟒蛇:

def MyMethod():

    print 'Hello from a method.'

    def MyInnerMethod():
        print 'Hello from a nested method.'

    MyInnerMethod()
Run Code Online (Sandbox Code Playgroud)

C#(使用.NET 3.5中的新功能):*

static void Main()
{
    Console.WriteLine("Hello from main.");

    Func<int, int> NestedMethod =
        (x) =>
        {
            Console.WriteLine("In nested method. Value of x is {0}.", x);
            return x;
        };

    int result = NestedMethod(3);
}
Run Code Online (Sandbox Code Playgroud)

那么为什么嵌套方法如此重要?是什么让他们有用?


**C#代码尚未经过测试.如果不编译,请随意编辑.*

Cha*_*iam 16

首先,意识到我不能给你一个完整的清单.如果你问"为什么螺丝刀有用?",我会谈论螺丝和油漆罐盖,但会在白蚁检查中忽略它们的价值.当你问"为什么嵌套函数有用?"时,我可以告诉你有关范围,闭包和入口点的信息.

首先,嵌套可以替代类.我最近写了一些渲染代码,它采用专门的标记代码的文件名并返回一个位图.这自然会导致名为grab_markup_from_filename()和render_text_onto_image()等函数.最干净的组织是一个名为generate_png_from_markup_filename()的入口点.入口点完成了它的工作,使用嵌套函数来完成它的任务.没有必要上课,因为没有国家的对象.我的另一种方法是使用私有方法创建一个隐藏我的助手的模块,但它会更加混乱.

def generate_png_from_markup_filename(filename):
    def grab_markup_from_filename():
        ... 
    ... # code that calls grab_markup_from_filename() to make the image
    return image
Run Code Online (Sandbox Code Playgroud)

其次,我使用嵌套来封闭.最常见的例子是创建装饰器.诀窍是我返回对内部函数的引用,因此内部函数和外部参数值不会被垃圾收集.

def verify_admin(function_to_call):
    def call_on_verify_admin(*args, **kwargs):
        if is_admin(global.session.user):
            return function_to_call(*args, **kwargs)
        else:
           throw Exception("Not Admin")
    return call_on_verify_admin  # the return value of verify_admin()
Run Code Online (Sandbox Code Playgroud)

用这种方式:

 def update_price(item, price):
     database.lookup(item).set_field('price', price)
 update_price = verify_admin(update_price)
Run Code Online (Sandbox Code Playgroud)

或者,更简洁地说:

 @verify_admin
 def update_price(item, price):
     database.lookup(item).set_field('price', price)
Run Code Online (Sandbox Code Playgroud)

是的,它应该很难追查.请记住,"def"只是另一种说法.

所以,这里有两个地方嵌套类很有帮助.还有更多.这是一个工具.


Nad*_*zie 8

嵌套方法很有用,因为在许多情况下,您希望传递行为,而不仅仅是数据.在许多情况下,除了更容易和更快速地编写之外,更清晰,更容易理解,只需在方法体中定义该行为,您将在其中使用它.

在.NET中,LINQ就是一个很好的例子.假设您要创建一个列表,其中每个值都是原始列表中值的两倍:

list.Select(i => i*2)
Run Code Online (Sandbox Code Playgroud)

在哪里i => i*2相当于:

Func<int,int> double = delegate(int x) { return x*2; }
Run Code Online (Sandbox Code Playgroud)

这是很多不是创建一个单独的功能简单和清晰.

此外,您声明的函数在其他地方可能没有意义(即,在您的方法范围之外).在C#中,您甚至可以引用在方法体内声明的变量 - 您无法使用非嵌套函数.

当然,你也可以滥用嵌套函数......


Gra*_*rdx 5

嵌套方法还允许您控制调用者的范围,并允许您访问内部创建的成员,而无需将它们暴露给类似范围内的其他函数(即在类内部)


Kon*_*rin 5

嵌套方法增加了代码的局部性,这是一件好事,因为您不必使用仅在一个地方使用的小型私有方法来污染类。