如何通过字符串指定参数的字段访问器?DevExpress报表开发求助
动态访问Notice类字段的解决方案
你遇到的问题是C#不支持直接通过字符串变量访问类的成员,notice.{elementName}这种写法语法不合法。下面是三种可行的解决办法,按需选择:
方法一:使用反射(快速实现,无需修改Notice类)
反射可以通过字符串获取类的字段或属性值,适合字段数量不多、性能要求不高的场景:
private static void BuildReportHeader(Notice notice, XRControl control) { if (control.Name.StartsWith("lbl")) { string elementName = control.Name.Substring(3); XRLabel label = (XRLabel)control; // 优先尝试获取属性(如果Notice用的是属性而非字段) var property = typeof(Notice).GetProperty(elementName); if (property != null) { label.Text = property.GetValue(notice)?.ToString() ?? string.Empty; return; } // 如果是字段则走这里 var field = typeof(Notice).GetField(elementName); if (field != null) { label.Text = field.GetValue(notice)?.ToString() ?? string.Empty; } } }
注:如果Notice类的成员是私有/保护的,需要在GetProperty/GetField里传入BindingFlags.NonPublic | BindingFlags.Instance参数。
方法二:预定义字典映射(性能最优,适合高频调用)
提前把字段名和对应的取值逻辑存入字典,避免反射的性能损耗:
// 静态字典,初始化一次即可 private static readonly Dictionary<string, Func<Notice, string>> _noticeFieldMap = new Dictionary<string, Func<Notice, string>> { { "Title", n => n.Title?.ToString() }, { "CreateTime", n => n.CreateTime.ToString("yyyy-MM-dd") }, { "Content", n => n.Content }, // 按Notice的实际字段/属性添加更多映射 }; private static void BuildReportHeader(Notice notice, XRControl control) { if (control.Name.StartsWith("lbl") && _noticeFieldMap.TryGetValue(control.Name.Substring(3), out var getter)) { XRLabel label = (XRLabel)control; label.Text = getter(notice) ?? string.Empty; } }
这种方式性能比反射好很多,而且可以统一处理格式(比如日期格式化),但需要维护字典和Notice类的字段同步。
方法三:给Notice类添加索引器(需修改Notice类)
如果有权限修改Notice类,可以添加一个字符串索引器,内部处理字段映射:
public class Notice { // 原有字段/属性 public string Title { get; set; } public DateTime CreateTime { get; set; } public string Content { get; set; } // 添加索引器 public string this[string fieldName] { get { return fieldName switch { "Title" => Title, "CreateTime" => CreateTime.ToString("yyyy-MM-dd"), "Content" => Content, _ => string.Empty }; } } } // 调用代码简化为: private static void BuildReportHeader(Notice notice, XRControl control) { if (control.Name.StartsWith("lbl")) { string elementName = control.Name.Substring(3); XRLabel label = (XRLabel)control; label.Text = notice[elementName]; } }
这种方式调用最简洁,索引器内部可以灵活处理格式和默认值,但依赖对Notice类的修改权限。
内容的提问来源于stack exchange,提问作者JacobPelley
相关产品推荐
相关产品推荐

