在C#应用中查找含指定Attribute的变量时遇类型转换错误
解决TwinCAT ADS查找带特定Attribute变量时的类型转换错误
问题场景
在C#项目中通过TwinCAT ADS查找带有特定Attribute的变量时,运行代码出现以下错误:
Error: Unable to cast object of type 'TwinCAT.TypeSystem.DynamicVirtualStructInstance' to type 'TwinCAT.Ads.TypeSystem.IAdsSymbol'
原代码如下:
class Program { static void Main() { try { using (AdsClient Client = new AdsClient()) { // 连接TwinCAT ADS路由器 Client.Connect("172.18.233.27.1.1", 851); // 创建符号加载器 SymbolLoaderSettings settings = new SymbolLoaderSettings(SymbolsLoadMode.DynamicTree); IAdsSymbolLoader dynLoader = (IAdsSymbolLoader)SymbolLoaderFactory.Create(Client, settings); // 查找带有指定Attribute的符号 string desiredAttribute = "AddToConfig"; foreach (IAdsSymbol symbol in dynLoader.Symbols) { if ( symbol.Attributes.Contains(desiredAttribute)) { // 对符合条件的符号执行操作 Console.WriteLine($"符号名称: {symbol.InstanceName}"); Console.WriteLine($"符号路径: {symbol.InstancePath}"); // ... 其他操作 } } } } catch (Exception ex) { Console.WriteLine($"错误: {ex.Message}"); } Console.WriteLine("按任意键退出..."); Console.ReadKey(); } }
错误原因
使用SymbolsLoadMode.DynamicTree模式加载符号时,dynLoader.Symbols集合中不仅包含IAdsSymbol类型的变量符号,还会混入结构体实例(DynamicVirtualStructInstance类型)。直接将集合内所有元素强制转为IAdsSymbol,就会触发类型转换异常。
解决方案
有两种可行的修复方式:
方式一:遍历前筛选出IAdsSymbol类型元素
通过LINQ的OfType<IAdsSymbol>方法,只遍历符合目标类型的符号:
class Program { static void Main() { try { using (AdsClient Client = new AdsClient()) { Client.Connect("172.18.233.27.1.1", 851); SymbolLoaderSettings settings = new SymbolLoaderSettings(SymbolsLoadMode.DynamicTree); IAdsSymbolLoader dynLoader = (IAdsSymbolLoader)SymbolLoaderFactory.Create(Client, settings); string desiredAttribute = "AddToConfig"; // 仅筛选IAdsSymbol类型的元素进行遍历 foreach (IAdsSymbol symbol in dynLoader.Symbols.OfType<IAdsSymbol>()) { if (symbol.Attributes.Contains(desiredAttribute)) { Console.WriteLine($"符号名称: {symbol.InstanceName}"); Console.WriteLine($"符号路径: {symbol.InstancePath}"); } } } } catch (Exception ex) { Console.WriteLine($"错误: {ex.Message}"); } Console.WriteLine("按任意键退出..."); Console.ReadKey(); } }
方式二:修改符号加载模式为Flat
如果不需要树形结构的符号层级,直接使用SymbolsLoadMode.Flat模式加载,此时dynLoader.Symbols中只会包含IAdsSymbol类型的元素:
// 将加载模式改为Flat SymbolLoaderSettings settings = new SymbolLoaderSettings(SymbolsLoadMode.Flat);
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

