C#:无需反射如何访问不同对象中的同名同类型属性?
无需反射访问多类同名属性的实现方案
方案1:定义统一接口(最推荐)
给所有订阅者类定义一个包含msisdn属性的接口,让每个类都实现该接口,之后直接通过接口类型访问属性,完全规避反射带来的性能损耗,同时还能获得编译时类型安全检查。
代码示例:
// 定义统一接口 public interface ISubscriber { string Msisdn { get; set; } } // 修改现有类实现接口 public class RedSubscriber : ISubscriber { public string Msisdn { get; set; } public string Imsi { get; set; } // 其他专属属性 } public class BlueSubscriber : ISubscriber { public string Msisdn { get; set; } public string Imei { get; set; } // 其他专属属性 } // 获取msisdn的方法 public void GetSubscriberMsisdn(ISubscriber subscriber) { string msisdnValue = subscriber.Msisdn; if (!string.IsNullOrEmpty(msisdnValue)) { Debug.WriteLine($"The msisdn is: {msisdnValue}"); } }
方案2:使用基类
如果这些订阅者类可以共用一个继承链,可将msisdn属性抽离到基类中,子类直接继承基类即可。
代码示例:
// 定义基类 public abstract class BaseSubscriber { public string Msisdn { get; set; } } // 子类继承基类 public class RedSubscriber : BaseSubscriber { public string Imsi { get; set; } // 其他专属属性 } public class BlueSubscriber : BaseSubscriber { public string Imei { get; set; } // 其他专属属性 } // 获取msisdn的方法 public void GetSubscriberMsisdn(BaseSubscriber subscriber) { string msisdnValue = subscriber.Msisdn; if (!string.IsNullOrEmpty(msisdnValue)) { Debug.WriteLine($"The msisdn is: {msisdnValue}"); } }
注意:C#不支持多继承,如果类已有其他基类,优先选择接口方案。
方案3:C# 9+ 记录类型+接口(简洁写法)
如果使用C# 9及以上版本,记录类型可以更简洁地实现接口,适合作为数据载体的订阅者类:
public interface ISubscriber { string Msisdn { get; } } public record RedSubscriber(string Msisdn, string Imsi) : ISubscriber; public record BlueSubscriber(string Msisdn, string Imei) : ISubscriber; public record YellowSubscriber(string Msisdn, string Iccid) : ISubscriber; // 获取方法和方案1一致 public void GetSubscriberMsisdn(ISubscriber subscriber) { Debug.WriteLine($"The msisdn is: {subscriber.Msisdn}"); }
方案4:源生成器(适用于无法修改原有类的场景)
如果不能修改现有订阅者类(比如来自第三方类库),可以用C#源生成器在编译时自动生成访问msisdn的扩展方法,既不用反射,也不改动原有代码。
生成的扩展方法示例:
public static class SubscriberExtensions { public static string GetMsisdn(this RedSubscriber subscriber) { return subscriber.Msisdn; } public static string GetMsisdn(this BlueSubscriber subscriber) { return subscriber.Msisdn; } // 其他类的扩展方法 }
调用方式:
var redSub = new RedSubscriber { Msisdn = "123456" }; Debug.WriteLine($"The msisdn is: {redSub.GetMsisdn()}");
内容的提问来源于stack exchange,提问作者Felipe La Rotta
相关产品推荐
相关产品推荐

