C#传入父接口类型参数时显式接口实现不生效如何解决
问题根因
你当前的实现方案中,IHiddenItems 使用 new 关键字定义的 Items 是独立的全新属性签名,和 IHasItems 声明的 Items 不存在重写关系。当入参类型为 IHasItems 的 PrintItems 方法被调用时,运行时只会绑定 IHasItems 对应的属性实现,也就是返回3条数据的默认实现,和你传入的对象是否额外实现了IHiddenItems没有关联。
可行实现方案
以下方案均不需要修改现有PrintItems方法,也不需要重新创建原对象实例并手动清空条目。
方案1:轻量代理包装类(无侵入,推荐)
仅新增一个极简的代理包装类,在需要隐藏条目的场景下把原对象包一层传入即可,完全不需要修改原有类的逻辑:
// 新增空条目代理类,实现IHasItems接口 public class HiddenItemsWrapper : IHasItems { private readonly IHasItems _original; public HiddenItemsWrapper(IHasItems original) { _original = original; } // 仅Items返回空列表,其他需要保留的原对象成员可以直接转发到_original public IEnumerable<string> Items => Enumerable.Empty<string>(); }
调用时修改传入逻辑即可:
// 原来的调用代码 // PrintItems(((IHiddenItems)derivedClass)); // 替换为 PrintItems(new HiddenItemsWrapper(derivedClass));
如果不需要保留原对象的其他功能,也可以把包装类做成单例,不需要每次传入原对象,进一步减少开销。
方案2:调整原实现类的接口绑定逻辑
如果不想新增类,可以修改原实现类的IHasItems属性显式实现逻辑,和隐藏状态联动:
public class Implementation : IHasItems, IHiddenItems { public Implementation() { Items = new List<string>() { "A","B","C" }; } public IEnumerable<string> Items { get; } // 新增隐藏状态标志 private bool _isItemsHidden; // 显式实现IHasItems的Items,根据隐藏状态返回对应值 IEnumerable<string> IHasItems.Items => _isItemsHidden ? Enumerable.Empty<string>() : Items; // 访问IHiddenItems的Items时自动设置隐藏标志 IEnumerable<string> IHiddenItems.Items { get { _isItemsHidden = true; return Enumerable.Empty<string>(); } } }
调用时触发一次隐藏状态设置即可:
var hiddenObj = (IHiddenItems)derivedClass; // 访问一次IHiddenItems的Items触发隐藏 _ = hiddenObj.Items; PrintItems(hiddenObj);
注意该方案会修改原对象的全局状态,后续所有通过IHasItems访问该对象的Items都会返回空,适合对象生命周期内仅需要隐藏一次的场景。
内容的提问来源于stack exchange,提问作者Le Vu
相关产品推荐
相关产品推荐

