大山的LabVIEW/TestStand分享大山的LabVIEW/TestStand分享

面向 LabVIEW 与 TestStand 的个人知识分享站

LabVIEW vs C#:Call By Reference与Delegate

LabVIEW vs C#:Call By Reference与Delegate

委托是 C# 最重要的基础特性之一——它在 LabVIEW 中最接近的概念就是 Call By Reference Node

Delegate
发布时间:2026-07-15阅读时长:30 分钟浏览 170访客仅可浏览正文内容
LabVIEW
VI Reference.png
C#
// 步骤1:声明委托类型(定义"什么样"的方法可以被引用)
//         输入: 两个 int    输出: int
delegate int MathOperation(int x, int y);
// 步骤2:写几个签名匹配的方法
static int Add(int a, int b)      => a + b;
static int Subtract(int a, int b) => a - b;
static int Multiply(int a, int b) => a * b;
// 步骤3:把方法"装进"委托变量 → 通过委托调用
MathOperation op = Add;
Console.WriteLine(op(3, 2));   // 5
三步走代码
// 步骤1:声明委托类型(定义"什么样"的方法可以被引用)
//         输入: 两个 int    输出: int
delegate int MathOperation(int x, int y);

// 步骤2:写几个签名匹配的方法
static int Add(int a, int b)      => a + b;
static int Subtract(int a, int b) => a - b;
static int Multiply(int a, int b) => a * b;

// 步骤3:把方法"装进"委托变量 → 通过委托调用
MathOperation op = Add;
Console.WriteLine(op(3, 2));   // 5

// 步骤4:一个变量,切换指向不同的方法
op = Subtract;
Console.WriteLine(op(3, 2));   // 1

// op 就像 LabVIEW 中一个可以切换 VI Ref 的端子
op = Multiply;
Console.WriteLine(op(3, 2));   // 6
指向实例方法
var sensor = new Sensor();
Func<string> getInfo = sensor.GetInfo;  // 指向实例方法
Console.WriteLine(getInfo());            // 调用 sensor.GetInfo()
回调模式
// 这个方法接受一个"操作"作为参数
// 调用时才知道具体用什么算法
static void CalculateAndPrint(int x, int y, MathOperation operation)
{
    int result = operation(x, y);
    Console.WriteLine($"结果是: {result}");
}

// 用法:最后一个参数传的是"方法",不是"数据"
CalculateAndPrint(10, 5, Add);      // 结果: 15
CalculateAndPrint(10, 5, Subtract); // 结果: 5

而在 C# 中这一切只需要一行 CalculateAndPrint(10, 5, Add)。这就是委托被称为 "方法即参数" 的由来。

多播委托
// 声明一个无参数、无返回值的委托类型
delegate void LogHandler(string msg);

static void LogToConsole(string msg)
    => Console.WriteLine($"[控制台] {msg}");
static void LogToFile(string msg)
    => Console.WriteLine($"[文件]   {msg} → log.txt");

// 多播:一个委托变量绑定两个方法
LogHandler logger = LogToConsole;
logger += LogToFile;   // 用 += 追加

// 一次调用,两个方法依次执行!
logger("系统启动");

// 输出:
//   [控制台] 系统启动
//   [文件]   系统启动 → log.txt

// 移除:用 -=
logger -= LogToFile;
logger("系统关闭");
// 输出:
//   [控制台] 系统关闭
内置委托签名适用场景
Action无参数、无返回值最简单的回调
Action<T>1 个参数、无返回值带数据的回调
Action<T1,T2>2 个参数、无返回值多参数回调(最多 16 个)
Func<TResult>无参数、有返回值工厂方法、懒加载
Func<T,TResult>1 参数、有返回值映射 / 转换(LINQ 大量使用)
EventHandler<T>void(object, T)事件处理(见事件相关文章)
内置委托
// 不需要自己声明委托,直接用内置的!
Action<string> log = Console.WriteLine;     // delegate void Action<T>(T obj);
Func<int, int, int> calc = Add;              // delegate TResult Func<T1,T2,TResult>(T1, T2);

log("Hello");    // 调用 Console.WriteLine("Hello")
calc(3, 2);      // 调用 Add(3, 2) → 5
委托范例
/* ═══════════════════════════════════════════════
 *  委托(Delegate)最简演示
 *  一句话理解:委托 = 可以把方法当参数传递
 *
 *  LabVIEW 对照:Call By Reference Node
 *  ═══════════════════════════════════════════════ */

using System;

// 步骤1:声明委托类型(定义"什么样的方法"可以被传递)
//         输入: 两个 int   输出: int
delegate int MathOperation(int x, int y);

// 步骤2:写几个签名匹配的方法
class Program
{
    static int Add(int a, int b)      => a + b;
    static int Subtract(int a, int b) => a - b;

    static void Main()
    {
        // 步骤3:把方法"装进"委托变量
        MathOperation op = Add;
        Console.WriteLine($"Add(3, 2)      = {op(3, 2)}");   // 5

        // 步骤4:换个方法,同样的变量
        op = Subtract;
        Console.WriteLine($"Subtract(3, 2) = {op(3, 2)}");   // 1

        // ── 委托作为方法参数 ──────────────────────
        // 这是委托最实用的场景:把"做什么"的决定权交给调用方
        Console.WriteLine();
        Console.WriteLine("把方法当参数传入:");
        CalculateAndPrint(10, 5, Add);         // 输出 15
        CalculateAndPrint(10, 5, Subtract);    // 输出 5
    }

    // 这个方法接受一个"操作"作为参数
    // 调用时才知道具体是加还是减
    // 类比 LabVIEW:VI 的输入端子连了一个 VI Reference
    static void CalculateAndPrint(int x, int y, MathOperation operation)
    {
        int result = operation(x, y);
        Console.WriteLine($"  计算结果是: {result}");
    }
}

/* ═══════════════════════════════════════════════
 *  运行输出:
 *  Add(3, 2)      = 5
 *  Subtract(3, 2) = 1
 *
 *  把方法当参数传入:
 *    计算结果是: 15
 *    计算结果是: 5
 *  ═══════════════════════════════════════════════ */

附件下载

留言区

只有注册用户可以留言和下载附件。立即注册已有账号,去登录
正在加载留言...