如何将集合中不同泛型类型的InfoElement转为对应InfoTag<T>?
解决InfoElement转对应泛型InfoTag的问题
首先明确:你之前用InfoTag<dynamic>或InfoTag<object>转换失败,核心原因是不同封闭泛型类型之间没有继承关系——InfoTag<bool>和InfoTag<object>是完全独立的类型,所以as转换会直接返回null。
下面提供几种可行的解决方案:
方案1:定义非泛型接口/基类(推荐)
给InfoTag<T>提取一个非泛型的公共接口,把不需要泛型的属性和方法抽离出来,遍历的时候直接转换到这个接口,无需关心具体泛型参数。
步骤1:定义非泛型接口
public interface IInfoTag { string Terminator { get; set; } char TypeChar { get; set; } // 统一的Parse方法,返回object类型适配所有泛型结果 object Parse(string input); }
步骤2:让InfoTag实现该接口
public abstract class InfoElement {} public class InfoTag<T> : InfoElement, IInfoTag { public Func<string, T> Parser { get; set; } public string Terminator { get; set; } public char TypeChar { get; set; } // 实现接口的Parse方法,内部调用泛型Parser public object Parse(string input) { return Parser?.Invoke(input); } }
步骤3:遍历转换使用
foreach (InfoElement element in tagSet) { if (element is IInfoTag tag) { // 直接访问公共属性 Console.WriteLine($"终止符:{tag.Terminator},类型标识:{tag.TypeChar}"); // 调用Parse处理输入 var result = tag.Parse("测试输入"); // 可根据实际类型进一步处理结果 if (result is bool boolResult) { // 处理bool类型结果 } } }
方案2:模式匹配针对具体泛型类型
如果提前知道所有可能的T类型(比如只有bool、string等有限几种),可以用switch模式匹配直接匹配具体的InfoTag<T>:
foreach (InfoElement element in tagSet) { switch (element) { case InfoTag<bool> boolTag: // 处理bool类型标签,比如调用解析方法 var boolVal = boolTag.Parser("true"); break; case InfoTag<string> stringTag: // 处理string类型标签 var strVal = stringTag.Parser("hello"); break; // 添加其他已知泛型类型的case default: // 处理未知类型逻辑 break; } }
方案3:反射处理未知泛型类型
如果无法提前确定T的类型,可以用反射获取泛型信息并操作:
foreach (InfoElement element in tagSet) { var tagType = element.GetType(); // 判断当前对象是否是InfoTag<>的封闭泛型实例 if (!tagType.IsGenericType || tagType.GetGenericTypeDefinition() != typeof(InfoTag<>)) continue; // 获取Terminator和TypeChar属性值 string terminator = tagType.GetProperty("Terminator")?.GetValue(element) as string; char typeChar = (char)(tagType.GetProperty("TypeChar")?.GetValue(element) ?? default); // 获取并调用Parser委托 Delegate parser = tagType.GetProperty("Parser")?.GetValue(element) as Delegate; if (parser != null) { object result = parser.DynamicInvoke("示例输入"); // 处理结果,比如输出类型和值 Console.WriteLine($"结果类型:{result.GetType()},值:{result}"); } }
内容的提问来源于stack exchange,提问作者indepthx
相关产品推荐
相关产品推荐

