C# 嵌套方法?为什么它们有用?
所以我只是在学习C#和Python中的一些新东西。事实证明这两种语言都支持嵌套方法(C#类) Python: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
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年代早期),这也不是一项新发明
- 闭包:在别处提到过,但很有用。在封闭函数中使用局部变量初始化生成的函数,并返回自定义函数(或使用生成的代码)
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;
}