问题

c#匿名委托获取自身的方法?

回答
在C中,匿名委托(Lambda表达式)本身并不能直接“获取自身的方法”,因为匿名委托不是一个具有独立名称和实体的方法,它更像是一个嵌入到代码中的一段行为。但是,如果你想在匿名委托的执行过程中,引用并调用定义该匿名委托的代码块中的某个已经存在的方法,那倒是可以实现的。

我们来拆解一下这个问题,看看实际能做到什么:

核心点:匿名委托与普通方法的区别

首先,理解匿名委托和普通方法有什么不同是关键。

普通方法: 有一个明确的名称,可以被代码中的任何地方(在可见范围内)通过名称直接调用。它的生命周期和作用域是独立的。
匿名委托/Lambda表达式: 它们没有名字,它们是“一次性的”,通常作为参数传递给其他方法(比如事件处理、 LINQ查询、异步操作等),或者被赋值给委托类型的变量。它们的出现是为了简化代码,避免为一些简单的、一次性的逻辑去声明一个命名方法。

那么,当你说“获取自身的方法”时,你可能指的是以下几种情况:

1. 在匿名委托内部调用外部(当前作用域)的已命名方法:
这是最常见也最直接的用法。假设你有一个类,里面定义了一个普通的方法 `DoSomething()`,然后你创建了一个匿名委托,并且在这个匿名委托的逻辑里,你想调用 `DoSomething()`。

```csharp
public class MyClass
{
public void DoSomething()
{
Console.WriteLine("我是一个已经命名的方法,被匿名委托调用了。");
}

public void SetupOperation()
{
// 这是一个匿名委托,它绑定了一个Action委托类型
Action myAnonymousDelegate = () =>
{
Console.WriteLine("这是匿名委托内部的代码。");
// 在这里,我们直接调用了当前类(MyClass)的另一个普通方法
this.DoSomething(); // 或者直接 DoSomething(); 也可以
};

// 执行匿名委托
myAnonymousDelegate();
}
}

// 调用示例
MyClass obj = new MyClass();
obj.SetupOperation();
```

详细解释:
在这个例子里,`myAnonymousDelegate` 是匿名委托。当它被执行时(`myAnonymousDelegate()`),它的内部代码块就会运行。在这个代码块里,`this.DoSomething()` 实际上是通过`this`引用(指向`MyClass`的实例)来访问并调用`MyClass`类中名为`DoSomething`的那个方法。这并不是匿名委托“获取自身”,而是它捕获了它被创建时所在的上下文(也就是`MyClass`的实例,通过`this`),从而能够调用该实例上的方法。

2. 将匿名委托赋值给一个变量,然后通过这个变量调用它:
有时,我们会把匿名委托赋值给一个委托类型的变量,然后再通过这个变量来执行它。这看起来像是“获取”了那个匿名委托本身,但本质上还是通过一个引用来调用。

```csharp
// 假设我们在一个方法里
void AnotherMethod()
{
// 定义一个匿名委托,并赋值给一个Action变量
Action anonymousAction = () =>
{
Console.WriteLine("这是匿名委托的代码。");
};

// 现在,我们通过 anonymousAction 这个变量来“获取”并执行这个匿名委托
Console.WriteLine("准备调用匿名委托...");
anonymousAction(); // 通过变量调用
Console.WriteLine("匿名委托调用完毕。");
}

// 调用示例
AnotherMethod();
```

详细解释:
这里,`anonymousAction` 是一个变量,它的类型是 `Action` 委托。`Action` 是一种委托类型,它可以指向一个不接受参数也不返回任何值的方法。我们将一个匿名委托赋值给了这个变量。当调用 `anonymousAction()` 时,实际上是执行了那个匿名委托所代表的代码。这可以说是通过一个“名称”(变量名)来“指向”并调用匿名委托,但仍然不是匿名委托在运行时获得它自身的“方法定义”。

3. 在匿名委托内部,传递自身作为参数(较少见,但理论上可以):
某些场景下,你可能需要一个方法接受一个委托作为参数,然后在这个被调用的方法内部,再将这个委托传递出去,或者调用它。虽然这通常会通过一个已命名的委托变量来实现,但如果设计得足够巧妙,你也可以在创建匿名委托时,想办法让它“知道”自己被赋值给哪个变量(但这通常需要一些技巧,并且不是直接的“获取自身方法”)。

更常见的一种思路是,如果一个方法需要接收一个委托,并且在执行时需要调用这个委托,那么你可以在调用那个方法时,直接传递一个匿名委托。

```csharp
public delegate void MyDelegate(string message);

public void CallWithDelegate(MyDelegate del)
{
Console.WriteLine("CallWithDelegate 接收到委托,准备执行...");
del("来自 CallWithDelegate 的消息"); // 执行传进来的委托
Console.WriteLine("CallWithDelegate 执行完毕。");
}

// 在另一个方法里调用
public void ExecuteScenario()
{
// 创建一个匿名委托,并直接传递给 CallWithDelegate
CallWithDelegate((msg) =>
{
Console.WriteLine($"匿名委托被调用,接收到消息: {msg}");
// 如果需要,在这个匿名委托内部,它也可以调用其他方法,
// 就像我们在第一点看到的。
});
}

// 调用示例
MyClass obj = new MyClass(); // 假设 MyClass 包含 ExecuteScenario 和 CallWithDelegate
obj.ExecuteScenario();
```

详细解释:
`CallWithDelegate` 方法接收一个 `MyDelegate` 类型的参数 `del`。当我们在 `ExecuteScenario` 方法中调用 `CallWithDelegate((msg) => { ... })` 时,那个匿名委托 `(msg) => { ... }` 就被创建了,并且它被直接传递给了 `del` 参数。在 `CallWithDelegate` 内部,`del("来自 CallWithDelegate 的消息");` 这一行就执行了那个匿名委托。

总结一下:

C 的匿名委托(Lambda表达式)的核心价值在于表达行为,而不是拥有一个独立的、可被命名的实体。因此,它本身没有一个“自身的方法”可以去“获取”。

如果你想在匿名委托的代码块里调用其他方法: 你需要确保那些方法在匿名委托被创建时是可访问的。这通常是通过捕获外部变量(包括 `this` 关键字指向的当前对象)来实现的。
如果你想“引用”一个匿名委托: 你可以将它赋值给一个委托类型的变量,然后通过这个变量来调用它。

所以,与其说“匿名委托获取自身的方法”,不如理解为:匿名委托是在某个上下文中创建的,并且它可以访问或调用那个上下文中的其他方法或捕获的变量。 它的“能力”是源于它所处的环境,而不是它本身拥有的独立方法定义。

网友意见

user avatar

闭包捕获解决:

       EventHandler handler;  SceneManager.OnLoadComplete += handler = delegate {   //...   SceneManager.OnLoadComplete -= handler }        

类似的话题

  • 回答
    在C中,匿名委托(Lambda表达式)本身并不能直接“获取自身的方法”,因为匿名委托不是一个具有独立名称和实体的方法,它更像是一个嵌入到代码中的一段行为。但是,如果你想在匿名委托的执行过程中,引用并调用定义该匿名委托的代码块中的某个已经存在的方法,那倒是可以实现的。我们来拆解一下这个问题,看看实际能.............
  • 回答
    C 匿名类型属性被设计成只读,这背后有其深刻的理由,并非随意为之。理解这一点,需要我们深入挖掘匿名类型的本质和它在 C 语言中的定位。首先,我们得明白匿名类型是什么。它是一种在编译时创建的、没有显式声明的类型,其名称由编译器自动生成。你看到的“匿名”,指的就是你无法在代码中像定义普通类一样,通过 `.............
  • 回答
    C++ 匿名函数:实用至上,理性看待提到 C++ 的匿名函数,也就是我们常说的 lambda 表达式,在 C++11 标准出现之后,它就成了 C++ 语言中一个非常活跃且强大的特性。那么,对于这个新晋宠儿,我们应该持有怎样的态度呢?我认为,最合适不过的态度是——实用至上,理性看待。为什么说实用至上?.............
  • 回答
    在 C++ 中,循环内部定义与外部同名变量不报错,是因为 作用域(Scope) 的概念。C++ 的作用域规则规定了变量的可见性和生命周期。我们来详细解释一下这个过程:1. 作用域的定义作用域是指一个标识符(变量名、函数名等)在程序中可以被识别和使用的区域。C++ 中的作用域主要有以下几种: 文件.............
  • 回答
    C 语言的设计理念是简洁、高效、接近硬件,而其对数组的设计也遵循了这一理念。从现代编程语言的角度来看,C 语言的数组确实存在一些“不改进”的地方,但这些“不改进”很大程度上是为了保持其核心特性的兼容性和效率。下面我将详细阐述 C 语言为何不“改进”数组,以及这种设计背后的权衡和原因:1. 数组在 C.............
  • 回答
    C 语言王者归来,原因何在?C 语言,这个在编程界已经沉浮数十载的老将,似乎并没有随着时间的推移而消逝,反而以一种“王者归来”的姿态,在许多领域焕发新生。它的生命力如此顽强,甚至在 Python、Java、Go 等语言层出不穷的今天,依然占据着不可动摇的地位。那么,C 语言究竟为何能实现“王者归来”.............
  • 回答
    C罗拒绝同框让可口可乐市值下跌 40 亿美元,可口可乐回应「每个人都有不同的口味和需求」,这件事可以说是近几年体育界和商业界结合的一个典型案例,也引发了很多的讨论和思考。我们来详细地分析一下:事件本身: 核心行为: 在2021年欧洲杯小组赛葡萄牙对阵匈牙利的赛前新闻发布会上,葡萄牙球星克里斯蒂亚.............
  • 回答
    C++20 的协程(coroutines)和 Go 的 goroutines 都是用于实现并发和异步编程的强大工具,但它们的设计理念、工作方式以及适用的场景有显著的区别。简单地说,C++20 协程虽然强大且灵活,但与 Go 的 goroutines 在“易用性”和“轻量级”方面存在较大差距,不能完全.............
  • 回答
    在 C++ 中,为基类添加 `virtual` 关键字到析构函数是一个非常重要且普遍的实践,尤其是在涉及多态(polymorphism)的场景下。这背后有着深刻的内存管理和对象生命周期管理的原理。核心问题:为什么需要虚析构函数?当你在 C++ 中使用指针指向一个派生类对象,而这个指针的类型是基类指针.............
  • 回答
    在 C/C++ 中,采用清晰的命名规则是编写可维护、易于理解和协作代码的关键。一个好的命名规范能够让其他开发者(包括未来的你)快速理解代码的意图、作用域和类型,从而提高开发效率,减少 Bug。下面我将详细阐述 C/C++ 中推荐的命名规则,并提供详细的解释和示例。核心原则:在深入具体规则之前,理解这.............
  • 回答
    C++之所以没有被淘汰,尽管其被普遍认为“复杂”,其原因绝非单一,而是由一系列深刻的历史、技术和生态系统因素共同作用的结果。理解这一点,需要深入剖析C++的定位、优势、以及它所代表的工程哲学。以下是详细的解释: 1. 历史的沉淀与根基的稳固 诞生于C的土壤: C++并非凭空出现,它是对C语言的强.............
  • 回答
    C++ 模板:功能强大的工具还是荒谬拙劣的小伎俩?C++ 模板无疑是 C++ 语言中最具争议但也最引人注目的一项特性。它既能被誉为“代码生成器”、“通用编程”的基石,又可能被指责为“编译时地狱”、“难以理解”的“魔法”。究竟 C++ 模板是功能强大的工具,还是荒谬拙劣的小伎俩?这需要我们深入剖析它的.............
  • 回答
    C 语言本身并不能直接“编译出一个不需要操作系统的程序”,因为它需要一个运行环境。更准确地说,C 语言本身是一种编译型语言,它将源代码转换为机器码,而机器码的执行是依赖于硬件的。然而,当人们说“不需要操作系统的程序”时,通常指的是以下几种情况,而 C 语言可以用来实现它们:1. 嵌入式系统中的裸机.............
  • 回答
    C++ 中实现接口与分离(通常是通过抽象类、纯虚函数以及对应的具体类)后,确实会增加文件的数量,这可能会让人觉得“麻烦”。但这种增加的文件数量背后,隐藏着巨大的好处,使得代码更加健壮、灵活、可维护和可扩展。下面我将详细阐述这些好处:核心思想:解耦 (Decoupling)接口与实现分离的核心思想是解.............
  • 回答
    C++ 是一门强大而灵活的编程语言,它继承了 C 语言的高效和底层控制能力,同时引入了面向对象、泛型编程等高级特性,使其在各种领域都得到了广泛应用。下面我将尽可能详细地阐述 C++ 的主要优势: C++ 的核心优势:1. 高性能和底层控制能力 (Performance and LowLevel C.............
  • 回答
    C语言指针是否难,以及数学大V认为指针比范畴论还难的说法,是一个非常有趣且值得深入探讨的话题。下面我将尽量详细地阐述我的看法。 C语言指针:理解的“门槛”与“终点”首先,我们需要明确“难”的定义。在编程领域,“难”通常指的是: 学习曲线陡峭: 需要花费大量时间和精力去理解和掌握。 容易出错:.............
  • 回答
    在 C/C++ 中,指针声明的写法确实存在两种常见的形式:`int ptr;` 和 `int ptr;`。虽然它们最终都声明了一个指向 `int` 类型的指针变量 `ptr`,但它们在语法上的侧重点和历史演变上有所不同,导致了后者(`int ptr;`)更为普遍和被推荐。下面我将详细解释为什么通常写.............
  • 回答
    C++ 的核心以及“精通”的程度,这是一个非常值得深入探讨的话题。让我尽量详细地为您解答。 C++ 的核心究竟是什么?C++ 的核心是一个多层次的概念,可以从不同的角度来理解。我将尝试从以下几个方面来阐述:1. 语言设计的哲学与目标: C 的超集与面向对象扩展: C++ 最初的目标是成为 C 语.............
  • 回答
    C++ 和 Java 都是非常流行且强大的编程语言,它们各有优劣,并在不同的领域发挥着重要作用。虽然 Java 在很多方面都非常出色,并且在某些领域已经取代了 C++,但仍然有一些 C++ 的独特之处是 Java 无法完全取代的,或者说取代的成本非常高。以下是 C++ 的一些 Java 不能(或难以.............
  • 回答
    在 C/C++ 编程中,确实存在一些写法,它们本身可能不是最优的解决方案,甚至在大多数情况下是多余的,但却能让有一定经验的开发者眼前一亮,感到“不明觉厉”。这些写法往往巧妙地利用了语言的特性、预处理指令、或者是一些不常用的语法糖。同时,它们又不会像一些“炫技”般的操作那样显得过于怪异而难以理解。下面.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有