遍历IPet集合时,如何访问继承接口的抽象类的虚属性?
问题解决:无法访问PetBase的IsNameAPalindrome属性
问题根源在于House是List<IPet>类型,遍历取出的item是IPet接口实例,而IPet接口中并没有定义IsNameAPalindrome属性——该属性只在抽象类PetBase中存在,因此编译器无法识别这个属性。
以下是三种可行的解决方法:
方法一:扩展IPet接口,添加IsNameAPalindrome属性
直接在IPet接口中声明该属性,让PetBase实现它(已有虚实现无需额外修改),这样所有实现IPet的类(这里就是继承PetBase的派生类)都会具备这个属性:
public interface IPet { string Name { get; set; } bool IsNameAPalindrome { get; } // 新增属性声明 } public abstract class PetBase : IPet { public abstract string Name { get; set; } public virtual bool IsNameAPalindrome { get { return Name.Equals(string.Join("", Name.Reverse()), StringComparison.OrdinalIgnoreCase); // 建议添加忽略大小写判断,避免"Izzi"和"IZZI"结果不一致 } } }
之后遍历House时,直接访问item.IsNameAPalindrome即可:
foreach (var item in house) { Console.WriteLine($"{item.Name,-8} {item.IsNameAPalindrome}"); }
方法二:遍历类型转换为PetBase
如果不想修改IPet接口,可以在遍历的时候将item安全转换为PetBase类型,再访问属性:
foreach (var item in house) { if (item is PetBase pet) { Console.WriteLine($"{pet.Name,-8} {pet.IsNameAPalindrome}"); } }
这里用is模式匹配做安全转换,避免类型转换失败抛出异常。
方法三:新增专用接口,保持原IPet不变
如果需要避免修改原IPet接口,可以新增一个继承自IPet的接口,让PetBase实现它,同时修改House的类型:
public interface IPetWithPalindrome : IPet { bool IsNameAPalindrome { get; } } public abstract class PetBase : IPetWithPalindrome { // 原有代码保持不变 } public class House : List<IPetWithPalindrome> { }
这样遍历House时,item类型是IPetWithPalindrome,可以直接访问IsNameAPalindrome属性。
内容的提问来源于stack exchange,提问作者Hina Khuman
相关产品推荐
相关产品推荐

