C#获取静态成员名称:遍历成员时如何得到定义的变量名
问题核心原因
nameof是C#编译时语法糖,只会在编译阶段替换为当前传入标识符的字面字符串,nameof(item)编译后直接固定为字符串"item",和运行时item指向的实例完全无关,因此无法通过该写法获取对应静态成员的名称。
可实现的方案汇总
方案1:字典映射方案(最简单,无额外性能开销,即网友提出的思路)
直接在返回结果中同时携带实例和对应的名称,编译时即可确定所有名称,没有运行时损耗:
public class MyClass { public static MyClass A = new MyClass(); public static MyClass B = new MyClass(); public static MyClass C = new MyClass(); // 修改返回类型为字典,key为实例,value为对应静态成员名称 public static Dictionary<MyClass, string> List() { return new Dictionary<MyClass, string>() { { A, nameof(A) }, { B, nameof(B) }, { C, nameof(C) }, }; } } // 调用代码对应修改 foreach (var kvp in MyClass.List()) { Debug.Print(kvp.Value); // 要操作实例取kvp.Key即可 }
方案2:新增Name属性方案(更符合面向对象设计,扩展性更强)
直接把名称信息绑定到实例本身,后续任意场景使用都不需要额外做映射:
public class MyClass { // 新增属性存储实例对应的名称 public string Name { get; init; } // 初始化静态成员时赋值对应名称 public static MyClass A = new MyClass { Name = nameof(A) }; public static MyClass B = new MyClass { Name = nameof(B) }; public static MyClass C = new MyClass { Name = nameof(C) }; public static IEnumerable<MyClass> List() => new[] {A,B,C }; } // 调用代码 foreach (var item in MyClass.List()) { Debug.Print(item.Name); }
方案3:运行时反射方案(不推荐,仅做特殊场景参考)
如果完全不能修改原有MyClass的结构,可以用反射动态匹配静态成员名称,但是有性能开销,且实例重复时会出现匹配错误:
foreach (var item in MyClass.List()) { var memberName = typeof(MyClass) .GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static) .First(f => f.FieldType == typeof(MyClass) && Equals(f.GetValue(null), item)) .Name; Debug.Print(memberName); }
内容的提问来源于stack exchange,提问作者Mobz
相关产品推荐
相关产品推荐

