resx资源GetName可正常调用,传入Attribute参数时报错如何解决?
Attribute参数引用类库resx资源的解决方案
你当前使用的直接传入资源属性的方式无法实现,需调整实现逻辑,具体原因和可行方案如下:
报错原因说明
- 第一个报错 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type 是C#的语法强制限制:Attribute的参数必须是编译期可确定的常量、typeof表达式或对应参数类型的数组创建表达式。而resx文件自动生成的
MyCountry.GetName是运行时通过ResourceManager读取资源返回的静态属性,值在编译期无法确定,不符合参数要求。 - 第二个报错 The type name 'GetName' does not exist in the type 'MyCountry' 是因为
typeof运算符后必须跟类型名,GetName是MyCountry类下的属性而非类型,自然无法识别。
可行解决方案
方案1:调整Attribute定义(推荐,无硬编码维护成本)
如果TreeAttribute是你可以修改源码的自定义Attribute,可以新增支持资源读取的构造函数,运行时动态拉取资源值:
- 修改Attribute的构造逻辑:
public class TreeAttribute : Attribute { public string FirstParam { get; } public string SecondParam { get; } // 新增支持资源传入的构造函数 public TreeAttribute(Type resourceType, string resourceKey, string secondParam) { SecondParam = secondParam; // 运行时读取资源值,也可以把resourceType和resourceKey存下来,用到的时候再读取 var resourceManager = new System.Resources.ResourceManager(resourceType); FirstParam = resourceManager.GetString(resourceKey, System.Globalization.CultureInfo.CurrentCulture); } // 保留原有构造函数兼容旧代码 public TreeAttribute(string firstParam, string secondParam) { FirstParam = firstParam; SecondParam = secondParam; } }
- 使用时按照如下格式编写即可:
[Tree(typeof(ClassLibrary.MyCountry), nameof(ClassLibrary.MyCountry.GetName), "SomethingThere")]
该写法完全符合C#语法要求:typeof返回的是编译期可确定的类型,nameof返回的是编译期常量字符串。
方案2:定义常量同步资源值(适合无法修改Attribute源码的场景)
如果TreeAttribute是第三方提供的无法修改源码,可以手动在资源类中定义和资源值同步的常量:
// 给自动生成的MyCountry资源类写partial扩展 public partial class MyCountry { // 常量值和resx中GetName的Value保持一致 public const string GetNameConstant = "你的资源对应值"; }
使用时直接传入常量即可:
[Tree(ClassLibrary.MyCountry.GetNameConstant), "SomethingThere"]
该方案的缺点是需要手动维护常量和resx值的同步,修改资源时要同步更新常量值。
内容的提问来源于stack exchange,提问作者Computer
相关产品推荐
相关产品推荐

