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

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

LabVIEW vs C#:继承与接口

LabVIEW vs C#:继承与接口

LabVIEW 2020 引入 Interface 之后,单继承 + 多接口的 OOP 模型在两种语言中完全对齐

inheritance
发布时间:2026-08-07阅读时长:20 分钟浏览 10访客仅可浏览正文内容
继承(Inheritance)= is-a
接口(Interface)= can-do
LabVIEW
C#
// 基类
public class Sensor
{
    public string Name { get; set; }
    public double Reading { get; set; }

    // virtual = 子类可以重写(对标 LabVIEW Dynamic Dispatch VI)
    public virtual string GetInfo()
        => $"传感器 \"{Name}\" 读数: {Reading}";
}

// 子类
// : Sensor = "继承自 Sensor"(对标 Change Parent Class)
public class TemperatureSensor : Sensor
{
    public string Unit { get; set; } = "°C";

    // override = 重写父类方法(对标 Create VI for Override)
    public override string GetInfo()
        => $"温度传感器 \"{Name}\" = {Reading}{Unit}";
}
C# 中声明和实现接口
// 声明接口(只有方法签名,没有实现、没有字段)
public interface ICalibratable
{
    void Calibrate();          // 校准
    bool IsCalibrated { get; } // 只读属性:是否已校准
}

public interface IDiagnosable
{
    string RunDiagnostics();   // 自检,返回诊断结果
}
  • C#:接口名以大写 I 开头(ICalibratable),这是 .NET 的传统
  • LabVIEW:不推荐 I 前缀,因为 LabVIEW 用图标区分类和接口(实心立方体 = 类,线框立方体 = 接口),命名区分不必要
  • 可以理解为"没有私有数据控件的类"(a class without a private data control)
  • 它声明对象"能扮演什么角色",但不定义如何扮演
  • 文件扩展名仍是 .lvclass,和普通类一样
  • 在项目浏览器中,类用实心立方体图标,接口用线框立方体图标
  • 1 个父类:通过 Change Parent Class 选择(只能选一个)
  • 多个接口:通过 Change Parent Interfaces 多选(想选几个选几个)
  • 接口也可以继承自其他接口
  • 一个类实现的所有接口方法都必须 override(Create VI for Override)
Interface.png
2020之前/之后对比
特性LabVIEW 2020+C#
父类继承Properties → Inheritance → Change Parent Class(只能 1 个)class X : Parent
接口声明右键项目 → New → Interfaceinterface IName { }
接口方法New VI → Dynamic Dispatch Template(只有连线板,无实现)只写方法签名,不带方法体
接口无数据没有 Private Data Control不能声明字段
实现多个接口Properties → Inheritance → Change Parent Interfaces → 多选class X : Parent, I1, I2, I3
重写虚方法右键 → Create VI for Overrideoverride 关键字
运行时类型判断Preserve Run-Time Class + To More Specific Classif (obj is IName x)
文件扩展名.lvclass(接口和类共用).cs
视觉区分实心立方体 = 类,线框立方体 = 接口I 前缀 = 接口
场景1
// 所有传感器,不管什么类型,都是 Sensor
List<Sensor> sensors = new()
{
    new TemperatureSensor { Name = "TC-01", Reading = 23.5 },
    new PressureSensor    { Name = "P-02",  Reading = 101.3 },
    new PrecisionSensor   { Name = "PS-A",  Reading = 42.0 }
};

// GetInfo() 会自动路由到正确的子类实现(Dynamic Dispatch)
foreach (var s in sensors)
    Console.WriteLine(s.GetInfo());

// 输出:
//   温度传感器 "TC-01" = 23.5°C
//   压力传感器 "P-02" = 101.3kPa
//   精密传感器 "PS-A" 读数: 42.000
场景2
// 只对有校准能力的传感器执行校准
foreach (var s in sensors)
{
    if (s is ICalibratable c)       // 运行时判断:这个对象能校准吗?
    {
        c.Calibrate();              // 能 → 校准它
        Console.WriteLine($"  \"{s.Name}\" 已校准");
    }
    else
    {
        Console.WriteLine($"  \"{s.Name}\" 不支持校准");
    }
}

// 输出:
//   "TC-01" 不支持校准
//   "P-02" 不支持校准
//   "PS-A" 已校准
场景3
var ps = new PrecisionSensor { Name = "PS-A", Reading = 42.0 };

// 把对象当作 ICalibratable 使用——只能用 Calibrate() 和 IsCalibrated
ICalibratable cal = ps;
cal.Calibrate();
// cal.Name  ← 编译错误!ICalibratable 没有 Name

// 把对象当作 IDiagnosable 使用——只能用 RunDiagnostics()
IDiagnosable diag = ps;
Console.WriteLine(diag.RunDiagnostics());
记忆口诀含义示例
is-a继承:子类 是 父类的一种TemperatureSensor is a Sensor
can-do接口:类 能做 某件事PrecisionSensor can Calibrate
1 + N1 个父类 + N 个接口class X : Parent, I1, I2

附件下载

留言区

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