跳到主要内容

OpcUaNodeId — 强类型 NodeId

概述

OPC UA 节点 ID 在 SDK 里默认用字符串编码 ("ns=2;s=Foo" / "i=84" / "g={GUID}" / "b=base64")。字符串方便日志和配置文件, 但在编程时容易踩:

  • 拼错前缀 (s= 写成 S=)
  • ns 索引漂移 (服务端动态注册命名空间)
  • GUID / Opaque 类型识别

OpcUaNodeIdreadonly record struct, 显式带 NamespaceIndex / IdType / Identifier 三件套, 与字符串 100% 互转。

对应规范段: Part 6 §5.2.2 (NodeId 编码)。

API

成员类别读写说明
OpcUaNodeId.Null静态空哨兵 (i=0)
OpcUaNodeId.FromNumeric(ns, uint id)工厂构造数字型
OpcUaNodeId.FromString(ns, string id)工厂构造字符串型
OpcUaNodeId.FromGuid(ns, Guid id)工厂构造 GUID 型
OpcUaNodeId.FromOpaque(ns, byte[] id)工厂构造不透明型
OpcUaNodeId.Parse(string s)静态解析字符串, 失败 throw FormatException
OpcUaNodeId.TryParse(s, out nid)静态安全解析
nid.ToString()方法序列化为 OPC UA 标准字符串
nid.NamespaceIndex属性命名空间索引 (ushort)
nid.IdType属性NodeIdType 枚举
nid.Identifier属性object 实际类型按 IdType
nid.IsNull属性是否为空

相关结构:

public enum NodeIdType
{
Numeric = 0, // i= 无符号 32 位整数 (最常见)
String = 1, // s= UTF-8 字符串
Guid = 2, // g= GUID {xxxx-...}
Opaque = 3 // b= base64 字节数组
}

代码示例

using DarraOpcUa_Client;

// 1) 工厂构造
var n1 = OpcUaNodeId.FromNumeric(0, 84); // i=84 (Root)
var n2 = OpcUaNodeId.FromString(2, "Boiler1.Temp"); // ns=2;s=Boiler1.Temp
var n3 = OpcUaNodeId.FromGuid(3, Guid.NewGuid()); // ns=3;g={...}
var n4 = OpcUaNodeId.FromOpaque(4, new byte[] {1,2,3});

// 2) 解析字符串
var n5 = OpcUaNodeId.Parse("ns=2;s=Demo.Tag");
Console.WriteLine($"ns={n5.NamespaceIndex}, type={n5.IdType}, id={n5.Identifier}");

if (OpcUaNodeId.TryParse("ns=99;i=foo", out var n6)) // false (foo 不是 uint)
Console.WriteLine("ok");
else
Console.WriteLine("invalid");

// 3) 序列化回字符串
string s = n2.ToString(); // "ns=2;s=Boiler1.Temp"

// 4) 与 SDK 互转 — SDK 接口仍接受字符串, ToString() 直接喂
using var dv = ua.Read(n2.ToString());

// 5) 比较 / 字典 key (record struct 自动 Equals / GetHashCode)
var dict = new Dictionary<OpcUaNodeId, string>();
dict[n2] = "锅炉一温度";

// 6) Null 哨兵
if (n2 == OpcUaNodeId.Null) Console.WriteLine("空");
Console.WriteLine($"IsNull={OpcUaNodeId.Null.IsNull}");

字符串编码规则

编码说明
i=NNN数字型, ns=0 时省略 ns= 前缀
ns=N;i=NNN数字型, ns≠0
ns=N;s=XXX字符串型, XXX 是 UTF-8
ns=N;g={GUID}GUID, 大括号包裹标准格式
ns=N;b=base64==字节数组, base64 无 padding

最佳实践

  • 配置文件存字符串 — 持久化用 ToString(), 加载用 Parse()
  • 代码内部用强类型 — 字典 key / Equals 比较等场景, 强类型更安全
  • Numeric 优先 — i=NNN 最快 (uint 比较), 字符串型有 hash 开销
  • 不要拼字符串"ns=" + ns + ";s=" + id 容易出错, 用 FromString(ns, id).ToString()
  • TryParse 先于 Parse — 用户输入永远先 TryParse, 异常路径少写

跨语言对照

C#PythonJavaC++RustC
OpcUaNodeIdOpcUaNodeIdOpcUaNodeIdOpcUaNodeIdOpcUaNodeIdDarraUa_NodeId
ParseparseparseParseparseDarraUa_NodeId_Parse
FromNumericfrom_numericfromNumericFromNumericfrom_numericDarraUa_NodeId_FromNumeric
FromStringfrom_stringfromStringFromStringfrom_stringDarraUa_NodeId_FromString

下一步