如何传递DAC字段参数重构Acumatica的DisplayName获取代码?
问题
我有一段重复执行的代码,用于从指定DAC的各字段中获取DAC字段的DisplayName属性,希望将该代码重构为函数并仅传递必要参数,但无法找到优雅的方式处理DAC字段参数。
重复使用的代码示例:
string displayName = string.Empty; foreach (PXEventSubscriberAttribute attribute in ext.DefAddress.Cache.GetAttributes<Address.countryID>(newaddr)) { if (attribute is PXUIFieldAttribute) { PXUIFieldAttribute attrib = attribute as PXUIFieldAttribute; displayName = attrib.DisplayName; } }
期望的函数调用形式:
string displayName = GetDisplayName(Address.addressLine1, ext.DefAddress.Cache, newaddr);
其中Address.addressLine1为DAC字段,ext.DefAddress.Cache为PXCache实例,newaddr为Address DAC对象。
我尝试的函数无法运行:
protected string GetDisplayName(Type field, PXCache cache, Address DAC) { foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes<field>(DAC)) { if (attribute is PXUIFieldAttribute) { PXUIFieldAttribute attrib = attribute as PXUIFieldAttribute; displayName = attrib.DisplayName; } } }
无论尝试多少次,都无法解决如何将DAC字段作为参数传入函数的问题,希望得到帮助!
解决方案
在Acumatica中,PXCache.GetAttributes<TField>是泛型方法,无法直接通过Type参数动态指定泛型类型。以下是两种可行的优雅实现方式:
方法1:基于字段名的类型安全调用
利用nameof关键字避免硬编码字段名,结合PXCache.GetAttributes的非泛型重载:
protected string GetDisplayName(PXCache cache, object dac, string fieldName) { foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes(dac, fieldName)) { if (attribute is PXUIFieldAttribute uiField) { return uiField.DisplayName; } } return string.Empty; }
调用示例:
string displayName = GetDisplayName(ext.DefAddress.Cache, newaddr, nameof(Address.addressLine1));
方法2:Lambda表达式实现完全类型安全
通过Lambda表达式传递字段,编译时即可校验字段合法性,完全符合你期望的调用形式:
using System.Linq.Expressions; protected string GetDisplayName<TEntity, TField>(PXCache cache, TEntity dac, Expression<Func<TEntity, TField>> fieldExpression) { var memberExpression = fieldExpression.Body as MemberExpression; if (memberExpression == null) return string.Empty; string fieldName = memberExpression.Member.Name; foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes(dac, fieldName)) { if (attribute is PXUIFieldAttribute uiField) { return uiField.DisplayName; } } return string.Empty; }
调用示例:
string displayName = GetDisplayName(ext.DefAddress.Cache, newaddr, x => x.addressLine1);
关键优化点
- 修正原代码中
string.Empty()的错误写法,应为string.Empty - 找到
PXUIFieldAttribute后立即返回,无需遍历全部属性,提升执行效率 - 两种方法均兼容Acumatica的DAC属性获取逻辑,适配不同场景需求
内容的提问来源于stack exchange,提问作者KDub97
相关产品推荐
相关产品推荐

