如何隐藏实现

时间:2013-01-11 14:00:33

标签: c# oop

假设我有一个类库,其中任何内部类都可以访问以下接口:

interface myInterface
{
    string myProperty { get; set; } // notice setter.
}

但如果有人将这个类库添加到他们的项目中,他们会得到以下界面:

public interface myInterface
{
    string myProperty { get; }
}

最有效和最受欢迎的做法是什么?有一个接口实现另一个吗?

3 个答案:

答案 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; }
}

你应尽量避免使用它。