假设我有一个类库,其中任何内部类都可以访问以下接口:
interface myInterface
{
string myProperty { get; set; } // notice setter.
}
但如果有人将这个类库添加到他们的项目中,他们会得到以下界面:
public interface myInterface
{
string myProperty { get; }
}
最有效和最受欢迎的做法是什么?有一个接口实现另一个吗?
答案 0 :(得分:2)
让你的公共界面只有getter:
public interface myInterface
{
string myProperty { get; }
}
然后从中导出另一个只有内部的接口,它有一个setter:
internal interface myInternalInterface : myInterface
{
new string myProperty { get; set; }
}
您可以实现内部界面:
class myImplementation : myInternalInterface
{
public string myProperty{get; set;}
}
如果需要调用setter,可以将实例转换为内部接口并在其上调用它。这种方法有点像设计气味,所以要谨慎使用它。
答案 1 :(得分:1)
您可以让内部接口扩展公共接口,如下所示:
public interface MyInternalInterface: MyPublicInterface
{
string MyProperty { set; }
}
public interface MyPublicInterface
{
string MyProperty { get; }
}
internal class A: MyInternalInterface
{
public string MyProperty { get; set; }
}
public class Foo
{
private A _a = new A();
internal MyInternalInterface GetInternalA() { return _a; }
public MyPublicInterface GetA() { return _a; }
}
这样你就不需要任何演员表或任何东西了。
答案 2 :(得分:0)
我认为@adrianbanks的答案可能是对我的改进,但是我认为它确实不是(尽管很漂亮) - 因为你无法保证公共接口实例也会传递给你实现内部的 - 这个解决方案也是如此。还有一件事只有在实现类型为internal
时才有效 - 如果您想将公共类型作为标准接口实现或作为层次结构的基础提供,那么这是不好的。
这就是我使用的。给出:
interface myInterface
{
string myProperty { get; set; }
}
public interface myPublicInterface
{
string myProperty { get; }
}
首先,无法使myPublicInterface
继承myInterface
,因为编译器会抱怨不一致的可访问性。因此,您可以使用属性支持器显式实现内部实现,然后隐式实现公共实现:
public class MyClass : myInterface, myPublicInterface
{
private string _myProperty;
string myInterface.myProperty
{
get { return _myProperty; }
set { _myProperty = value; }
}
public string myProperty
{
get { return _myProperty; }
}
}
注意 - 在某些情况下,getter可能不适合私有支持者,但可能是一些从其他属性计算值的逻辑。在这种情况下 - 保持干燥 - 你可以将逻辑放在公共吸气剂中,并为明确的吸气剂提供:
string myInterface.myProperty
{
get { return MyProperty; }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { /*whatever complex logic is used to get the value*/ }
}
你可以反过来做,但你必须对内部界面做一个看起来很可怕的内联演员:
string myInterface.myProperty
{
get { /*whatever complex logic is used to get the value*/ }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { return ((myInterface)this).myProperty; }
}
你应尽量避免使用它。