- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
在 .NET Core 中,委托(Delegate)是一种类型安全的函数指针,它允许你将方法作为参数传递给其他方法,或者将方法存储在变量中以便稍后调用。委托在事件处理、回调机制以及异步编程中非常有用。理解委托的运行原理对于掌握 .NET Core 的高级编程技巧至关重要.
委托是一种引用类型,它引用一个或多个方法。委托定义了方法的签名(参数类型和返回类型),因此只有具有相同签名的方法才能被委托引用.
你可以通过 delegate 关键字来定义一个委托类型。例如:
// 定义一个委托类型
public delegate void GreetDelegate(string name);
这个委托类型 GreetDelegate 可以引用任何具有 void 返回类型和 string 参数的方法.
一旦定义了委托类型,你可以创建该委托的实例,并将方法赋值给它。例如:
// 与委托签名匹配的方法
public void Greet(string name)
{
Console.WriteLine($"Hello, {name}!");
}
// 创建委托实例并绑定方法
GreetDelegate del = new GreetDelegate(Greet);
在这个例子中,del 是一个委托实例,它引用了 Greet 方法.
你可以像调用方法一样调用委托:
// 调用委托
del("World");
这会调用 del 方法,并输出 "Hello, World!".
单播委托是指一个委托实例只能引用一个方法。这是最基本的委托类型.
public delegate void GreetDelegate(string message);
public void ShowMessage(string message)
{
Console.WriteLine(message);
}
GreetDelegate del = new GreetDelegate(ShowMessage);
del("Hello, World!"); // 输出:Hello, World!
多播委托是指一个委托实例可以引用多个方法。通过 += 运算符可以将多个方法添加到委托实例中,并通过 -= 运算符移除方法.
public void ShowMessage1(string message)
{
Console.WriteLine($"Message 1: {message}");
}
public void ShowMessage2(string message)
{
Console.WriteLine($"Message 2: {message}");
}
public void ShowMessage3(string message)
{
Console.WriteLine($"Message 3: {message}");
}
GreetMulticastDelegate del = new GreetMulticastDelegate(ShowMessage1);
del += ShowMessage2;
del += ShowMessage3;
del -= ShowMessage2;
del("Hello, World!");
在这个例子中,del 委托实例引用了多个方法:将ShowMessage1,ShowMessage2 和 ShowMessage3添加到了多播委托实例中,然后并通过 -= 运算符移除ShowMessage2。然后调用 del("Hello, World!") 时,三个方法都会被调用,输出如下:
Message 1: Hello, World!
//ShowMessage2方法已移除
Message 3: Hello, World!
泛型委托是 C# 中的一种特殊委托类型,它允许你定义可以处理多种数据类型的委托。通过使用泛型,你可以编写更通用、更灵活的代码,而不需要为每种数据类型单独定义委托.
以下是几个泛型委托的示例,展示了如何使用泛型委托处理不同类型的数据.
public delegate T MyGenericDelegate<T>(T arg);
public int Square(int x)
{
return x * x;
}
public string Reverse(string s)
{
return new string(s.Reverse().ToArray());
}
MyGenericDelegate<int> intDelegate = new MyGenericDelegate<int>(Square);
Console.WriteLine(intDelegate(5)); // 输出:25
MyGenericDelegate<string> stringDelegate = new MyGenericDelegate<string>(Reverse);
Console.WriteLine(stringDelegate("hello")); // 输出:olleh
MyGenericDelegate
实例化了一个处理 int
类型数据的委托。MyGenericDelegate
实例化了一个处理 string
类型数据的委托。public delegate TResult MyGenericDelegate<T1, T2, TResult>(T1 arg1, T2 arg2);
public int Add(int a, int b)
{
return a + b;
}
public string Concat(string s1, string s2)
{
return s1 + s2;
}
MyGenericDelegate<int, int, int> intDelegate = new MyGenericDelegate<int, int, int>(Add);
Console.WriteLine(intDelegate(3, 5)); // 输出:8
MyGenericDelegate<string, string, string> stringDelegate = new MyGenericDelegate<string, string, string>(Concat);
Console.WriteLine(stringDelegate("Hello, ", "World!")); // 输出:Hello, World!
MyGenericDelegate
实例化了一个处理两个 int
类型参数并返回 int
类型结果的委托。MyGenericDelegate
实例化了一个处理两个 string
类型参数并返回 string
类型结果的委托。C# 提供了一些内置的泛型委托类型,可以直接使用,而无需自定义委托.
Action
委托Action 委托用于引用没有返回值的方法。它可以有 0 到 16 个参数.
Action<string> action = (message) => Console.WriteLine(message);
action("Hello, World!"); // 输出:Hello, World!
Func
委托Func 委托用于引用有返回值的方法。它可以有 0 到 16 个参数,最后一个泛型参数是返回值类型.
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 5)); // 输出:8
Predicate
委托Predicate 委托用于引用返回布尔值的方法,通常用于条件判断.
Predicate<int> isEven = (num) => num % 2 == 0;
Console.WriteLine(isEven(4)); // 输出:True
匿名方法允许你直接定义委托的实现,而无需显式声明一个方法.
MyDelegate del = delegate(string message)
{
Console.WriteLine(message);
};
del("Hello, World!"); // 输出:Hello, World!
Lambda 表达式是一种更简洁的匿名方法写法,通常用于定义委托.
Action<string> action = (message) => Console.WriteLine(message);
action("Hello, World!"); // 输出:Hello, World!
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 5)); // 输出:8
事件是一种特殊的委托,通常用于实现观察者模式。事件委托通常与 EventHandler 或 EventHandler 一起使用.
public class Button
{
public event EventHandler Click;
public void OnClick()
{
Click?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
button.Click += (sender, e) => Console.WriteLine("Button clicked!");
button.OnClick(); // 输出:Button clicked!
}
}
异步委托允许你异步调用方法,通常与 BeginInvoke 和 EndInvoke 一起使用.
public delegate int MyAsyncDelegate(int x, int y);
public int Add(int a, int b)
{
return a + b;
}
MyAsyncDelegate del = new MyAsyncDelegate(Add);
IAsyncResult result = del.BeginInvoke(3, 5, null, null);
int sum = del.EndInvoke(result);
Console.WriteLine(sum); // 输出:8
动态委托允许你在运行时动态创建和调用委托.
public int Multiply(int a, int b)
{
return a * b;
}
var method = typeof(Program).GetMethod("Multiply");
var del = Delegate.CreateDelegate(typeof(Func<int, int, int>), null, method);
int result = (del as Func<int, int, int>)(3, 5);
Console.WriteLine(result); // 输出:15
委托的运行原理涉及到 .NET Core 的运行时机制和内部实现。以下是委托运行原理的关键点:
在 .NET Core 中,委托是一个类,它继承自 System.MulticastDelegate 类。System.MulticastDelegate 类又继承自 System.Delegate 类。委托类包含以下关键成员:
_target
:指向调用方法的对象实例(如果是静态方法,则为 null
)。_methodPtr
:指向方法的函数指针。_invocationList
:用于存储多播委托中的多个方法。当你调用委托时,.NET Core 运行时会执行以下步骤:
**null**
:如果委托实例为 null
,则会抛出 NullReferenceException
。**Invoke**
****方法:委托实例的 Invoke
方法会被调用,该方法会根据 _target
和 _methodPtr
调用实际的方法。_invocationList
不为 null
),则 Invoke
方法会遍历 _invocationList
,依次调用每个方法。.NET Core 对委托的调用进行了优化,以提高性能。例如,对于单播委托(即只引用一个方法的委托),.NET Core 会直接调用方法,而不需要通过 Invoke 方法.
委托在 .NET Core 中有多种应用场景,以下是一些常见的场景:
委托在事件处理中非常常见。事件是一种特殊的委托,它允许对象在发生某些事情时通知其他对象。例如:
C#public class Button
{
public event Action Click;
public void OnClick()
{
Click?.Invoke();
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
button.Click += () => Console.WriteLine("Button clicked!");
button.OnClick();
}
}
在这个例子中,Button 类定义了一个 Click 事件,当 OnClick 方法被调用时,事件处理程序会被触发.
委托可以用于实现回调机制,允许一个方法在完成时通知另一个方法。例如:
public void DoWork(Action callback)
{
// 执行一些工作
Console.WriteLine("Work is done.");
// 调用回调方法
callback?.Invoke();
}
public void Main()
{
DoWork(() => Console.WriteLine("Callback called."));
}
在这个例子中,DoWork 方法在完成工作后调用传入的回调方法.
委托在异步编程中也非常有用。例如,Task 类的 ContinueWith 方法允许你在任务完成时执行一个委托:
Task.Run(() => Console.WriteLine("Task is running..."))
.ContinueWith(task => Console.WriteLine("Task is completed."));
委托是 .NET Core 中一个非常强大的特性,它允许你将方法作为参数传递、存储和调用。理解委托的运行原理有助于你更好地利用这一特性,特别是在事件处理、回调机制和异步编程中。通过掌握委托,你可以编写更加灵活和可扩展的代码.
最后此篇关于.NETCore委托原理解析的文章就讲到这里了,如果你想了解更多关于.NETCore委托原理解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我一直在使用 AJAX 从我正在创建的网络服务中解析 JSON 数组时遇到问题。我的前端是一个简单的 ajax 和 jquery 组合,用于显示从我正在创建的网络服务返回的结果。 尽管知道我的数据库查
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在尝试运行 Android 应用程序时遇到问题并收到以下错误 java.lang.NoClassDefFoundError: com.parse.Parse 当我尝试运行该应用时。 最佳答案 在这
有什么办法可以防止etree在解析HTML内容时解析HTML实体吗? html = etree.HTML('&') html.find('.//body').text 这给了我 '&' 但我想
我有一个有点疯狂的例子,但对于那些 JavaScript 函数作用域专家来说,它看起来是一个很好的练习: (function (global) { // our module number one
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我需要编写一个脚本来获取链接并解析链接页面的 HTML 以提取标题和其他一些数据,例如可能是简短的描述,就像您链接到 Facebook 上的内容一样。 当用户向站点添加链接时将调用它,因此在客户端启动
在 VS Code 中本地开发时,包解析为 C:/Users//AppData/Local/Microsoft/TypeScript/3.5/node_modules/@types//index而不是
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我被赋予了将一种语言“翻译”成另一种语言的工作。对于使用正则表达式的简单逐行方法来说,源代码过于灵活(复杂)。我在哪里可以了解更多关于词法分析和解析器的信息? 最佳答案 如果你想对这个主题产生“情绪化
您好,我在解析此文本时遇到问题 { { { {[system1];1;1;0.612509325}; {[system2];1;
我正在为 adobe after effects 在 extendscript 中编写一些代码,最终变成了 javascript。 我有一个数组,我想只搜索单词“assemble”并返回整个 jc3_
我有这段代码: $(document).ready(function() { // }); 问题:FB_RequireFeatures block 外部的代码先于其内部的代码执行。因此 who
背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件。它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口。相当于去掉host,这样省掉了些
1.首先贴上我试验成功的代码 复制代码 代码如下: protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 X
【PHP代码】 复制代码 代码如下: $stmt = mssql_init('P__Global_Test', $conn) or die("initialize sto
在SQL查询分析器执行以下代码就可以了。 复制代码代码如下: declare @t varchar(255),@c varchar(255) declare table_cursor curs
前言 最近练习了一些前端算法题,现在做个总结,以下题目都是个人写法,并不是标准答案,如有错误欢迎指出,有对某道题有新的想法的友友也可以在评论区发表想法,互相学习🤭 题目 题目一: 二维数组中的
我是一名优秀的程序员,十分优秀!