我有一个实现接口的对象列表,以及该接口的列表:
public interface IAM { int ID { get; set; } void Save(); } public class concreteIAM : IAM { public int ID { get; set; } internal void Save(){ //save the object } //other staff for this particular class } public class MyList : List{ public void Save() { foreach (IAM iam in this) { iam.Save(); } } //other staff for this particular class }
之前的代码无法编译,因为编译器要求所有接口成员都是公共的.
internal void Save(){
但我不想让我的DLL外部保存ConcreteIAM
,它只应该通过保存MyList
.
有什么办法吗?
更新#1:大家好,感谢目前为止的答案,但这些都不是我需要的:
接口需要是公共的,因为它是来自dll外部的客户端将使用的签名,以及ID
我在该示例中没有费心写的其他属性以保持简单.
安德鲁,我不认为解决方案是创建一个工厂来创建另一个包含IAM
成员+保存的对象.我还在想......还有其他想法吗?
我想你不明白界面是什么.接口是合同.它指定对象以某种方式运行.如果一个对象实现了一个接口,那就意味着你可以依赖它实现所有接口的方法.
现在,考虑如果有一个像你要求的界面会发生什么 - 公共,但有一个内部成员.那是什么意思?外部对象只能实现公共方法,而不能实现内部方法.当您获得这样的外部对象时,您将只能调用公共方法,而不能调用内部方法,因为该对象无法实现它.换句话说 - 合同将无法履行.并非所有方法都会实施.
我认为在这种情况下的解决方案是将您的界面分成两部分.一个接口是公共的,这就是你的外部对象将实现的.另一个接口是内部的,包含您Save()
和其他内部方法.也许第二个界面甚至可以从第一个继承.然后,您自己的内部对象将实现这两个接口.这样您甚至可以区分外部对象(没有内部接口的对象)和内部对象.
创建另一个内部接口,并使用该方法的显式实现.
internal interface InternalIAM { void Save(); } public class concreteIAM : InternalIAM { void InternalIAM.Save() { } }
我不认为你应该在这里使用界面也许你应该使用类似的抽象基础:
public abstract class AM { public int ID { get; set; } internal abstract void Save(); } public class concreteIAM : AM { internal override void Save() { //Do some save stuff } }
仍然允许你这样做:
public class AMList : List{ public void SaveItems() { foreach (var item in this) { item.Save(); } } }
我认为最好的办法是将内部和公共成员分成两个独立的界面.如果继承接口,您仍然可以公开声明成员,但内部成员的可见性将由接口本身的可见性决定.
using System; public interface IPublic { void Public(); } internal interface IInternal : IPublic { void Internal(); } public class Concrete : IInternal { public void Internal() { } public void Public() { } }