如何通过字符串动态修改类调用路径以调用MyFunction()?
在C#中通过字符串动态调用成员方法的实现方案
C#作为静态类型语言,直接写myClass.a.MyFunction()无法将变量a的值解析为成员名称,但可以通过反射或自定义动态映射两种方式实现需求。
方案1:使用反射实现动态调用
通过反射可以在运行时获取MyClass的成员(属性/字段),再调用其MyFunction方法:
string a = "OtherClass1"; MyClass myClass = new MyClass(); // 1. 获取MyClass中对应名称的成员(优先属性,再字段) var memberInfo = myClass.GetType().GetProperty(a) as MemberInfo ?? myClass.GetType().GetField(a); if (memberInfo != null) { // 2. 获取成员实例 object otherClassInstance; if (memberInfo is PropertyInfo prop) otherClassInstance = prop.GetValue(myClass); else otherClassInstance = ((FieldInfo)memberInfo).GetValue(myClass); // 3. 调用MyFunction方法 otherClassInstance?.GetType().GetMethod("MyFunction")?.Invoke(otherClassInstance, null); }
注意事项:
- 如果成员是私有/保护类型,需要在
GetProperty/GetField中传入BindingFlags.NonPublic | BindingFlags.Instance参数 - 频繁调用反射会有性能开销,可提前缓存
Type、PropertyInfo、MethodInfo对象
方案2:自定义动态映射(更高效)
如果MyClass的成员是固定的,可以提前将成员实例存入字典,通过索引器实现类似动态调用的效果,避免反射的性能损耗:
// 先定义依赖类 public class OtherClass1 { public void MyFunction() => Console.WriteLine("OtherClass1.MyFunction"); } public class OtherClass2 { public void MyFunction() => Console.WriteLine("OtherClass2.MyFunction"); } public class MyClass { public OtherClass1 OtherClass1 { get; set; } public OtherClass2 OtherClass2 { get; set; } private readonly Dictionary<string, dynamic> _memberMap; public MyClass() { OtherClass1 = new OtherClass1(); OtherClass2 = new OtherClass2(); _memberMap = new Dictionary<string, dynamic> { { nameof(OtherClass1), OtherClass1 }, { nameof(OtherClass2), OtherClass2 } }; } // 自定义索引器,通过字符串键获取成员实例 public dynamic this[string memberName] => _memberMap.TryGetValue(memberName, out var instance) ? instance : null; } // 调用方式 string a = "OtherClass1"; MyClass myClass = new MyClass(); myClass[a].MyFunction(); // 直接通过索引器调用,效果和期望一致
优势:
- 性能远高于反射,适合频繁调用的场景
- 类型安全可控,避免反射的潜在错误
关键说明
直接写myClass.a.MyFunction()在C#中是不合法的,因为编译器会将a解析为MyClass的成员名称,而非变量a的字符串值。必须通过运行时动态解析的方式实现需求。
内容的提问来源于stack exchange,提问作者stackGreen
相关产品推荐
相关产品推荐

