Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 嵌套方法?为什么它们有用?_C#_Python - Fatal编程技术网

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

C# 嵌套方法?为什么它们有用?,c#,python,C#,Python,所以我只是在学习C#和Python中的一些新东西。事实证明这两种语言都支持嵌套方法(C#类) Python: def MyMethod(): print 'Hello from a method.' def MyInnerMethod(): print 'Hello from a nested method.' MyInnerMethod() C#(使用.NET 3.5中的新功能):* static void Main() { Console.Wr

所以我只是在学习C#和Python中的一些新东西。事实证明这两种语言都支持嵌套方法(C#类)

Python:

def MyMethod():

    print 'Hello from a method.'

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

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

static void Main()
{
Console.WriteLine(“来自main的你好”);
Func嵌套方法=
(x) =>
{
WriteLine(“在嵌套方法中,x的值为{0}.”,x);
返回x;
};
int结果=嵌套方法(3);
}
那么为什么嵌套方法如此重要呢?什么使它们有用



**C代码还没有经过测试。如果不编译,请随意编辑。*

嵌套方法非常有用,因为在许多情况下,您希望传递行为,而不仅仅是数据。在许多情况下,除了更容易、更快地编写之外,在方法体中定义该行为(在将要使用它的地方)更清晰、更容易遵循

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

list.Select(i => i*2)
其中
i=>i*2
相当于:

Func<int,int> double = delegate(int x) { return x*2; }
Func double=delegate(intx){return x*2;}
这比创建一个单独的函数更简单、更清晰

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


当然,您也可以滥用嵌套函数…

嵌套方法还允许您控制调用方的作用域,并允许您访问内部创建的成员,而不让它们暴露于类似作用域中的其他函数(即类内部)

试试这个Pythonish伪代码示例,看看这种技术的一个用例:

def MyMethod(base):
    base = expensivePreparation(base)
    def MyInnerMethod(some_modifier):
        doSomethingCoolWith(base, some_modifier)

    return MyInnerMethod

process = MyMethod(some_obj)
process(arg1)
process(arg2)

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

首先,嵌套可以替代类。我最近编写了一些渲染代码,该代码使用文件名作为专门的标记代码,并返回位图。这自然会导致从_filename()获得名为grab _markup _的函数,并将_text _渲染到_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
其次,我对闭包使用嵌套。最常见的例子是创建装饰器。诀窍是我返回对内部函数的引用,这样内部函数和外部参数值就不会被垃圾收集

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()
这样使用它:

 def update_price(item, price):
     database.lookup(item).set_field('price', price)
 update_price = verify_admin(update_price)
或者,更简洁地说:

 @verify_admin
 def update_price(item, price):
     database.lookup(item).set_field('price', price)
是的,应该很难追踪。记住,“def”只是另一个语句


因此,这里有两个地方嵌套类很有用。还有更多。这是一个工具。

这里已经有很多有用的答案了,但现在开始了

  • 内部阶级:不是!很好的尝试,但太多的工作。嵌套的函数/过程要快得多,而且切中要害。King Java的[1]类和一个方法[2]真的很差劲,而嵌套函数(或过程)避免了这种无意义的语法
  • 功能分解:将一个较长的例程分解为较小的例程,这些例程隐藏在其他不使用它们的地方。帕斯卡在亿万年前就支持这一点,我很确定即使在当时(70年代早期),这也不是一项新发明
  • 闭包:在别处提到过,但很有用。在封闭函数中使用局部变量初始化生成的函数,并返回自定义函数(或使用生成的代码)
1:“爪哇国王”


2:“函数对象/函子”

沿着上述各点,这些函数可以被视为高阶函数,它们本身接受或返回函数

看看这个例子:

     static void Main(string[] args)
    {

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

        HigerOrderTest(NestedMethod)();
    }

     private static Action HigerOrderTest(Func<int, int> highFunction)
    {
          var sam = highFunction(3);

          Action DoIt =() =>
          {
              Console.WriteLine("Output is {0}.", sam);    
          };
             return DoIt;
    }
static void Main(字符串[]args)
{
Func NestedMethod=委托(int x)
{Console.WriteLine(“在嵌套方法中,x的值为{0}.”,x);
返回x;
};
HigerOrderTest(嵌套方法)();
}
专用静态动作HigerOrderTest(函数highFunction)
{
var sam=高功能(3);
动作DoIt=()=>
{
WriteLine(“输出为{0}.”,sam);
};
返回DoIt;
}

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

您可能已经意识到将函数传递给其他函数的有用性,例如,提供带有比较函数的
排序()
例程,还有
map()
filter()
等明显的例子。同样,从另一个函数接收函数通常也是有用的。最常见的用法是for,但也很常见

闭包的一个主要好处是能够在运行时创建一个新函数,该函数包含在该时间点执行该函数所需的所有时间信息。在不支持闭包的语言实现中,这种状态管理通常是通过类完成的,可以说不那么优雅:设置对象实例变量,然后在需要时读取。闭包提供了一种将状态与操作捆绑在一起的方法

因此,作为理解的基本点,将嵌套函数视为在-
     static void Main(string[] args)
    {

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

        HigerOrderTest(NestedMethod)();
    }

     private static Action HigerOrderTest(Func<int, int> highFunction)
    {
          var sam = highFunction(3);

          Action DoIt =() =>
          {
              Console.WriteLine("Output is {0}.", sam);    
          };
             return DoIt;
    }