如何从C#中的接口隐藏已实现属性的set方法?

时间:2011-04-30 20:15:02

标签: c# inheritance interface encapsulation

向大家致意......

如果我有以下界面:

interface IMyInterface
{
    int property { get; set; }
}

以下实施:

class MyClass : IMyInterface
{
// anything
}

如何从set的实例隐藏属性的MyClass方法...换句话说,我不想set property方法公开,这可能吗?

使用抽象类很容易:

abstract class IMyInterface
{
    int property { get; protected set; }
}

然后我只能set实现上面抽象类的类中的property ...

6 个答案:

答案 0 :(得分:7)

开始时,界面中没有set。您仍然可以将其实现为private

你不能“隐藏”它,它是合同的一部分。如果您不希望它成为合同的一部分,请不要定义它。

答案 1 :(得分:2)

如果使用以下接口,则在通过接口操作类时,set方法将不可用:

interface IMyInterface
{ 
   int property { get; }
}

然后你可以像这样实现这个类:

class MyClass : IMyInterface
{
  int property { get; protected set; }
}

答案 2 :(得分:1)

假设您需要将setter作为接口的一部分,但由于某种原因,在特定的实现者(在本例中为MyClass)上使用它是没有意义的,您总是可以在setter中抛出异常(例如一个InvalidOperationException)。这不会在编译时保护您,仅在运行时。但是有点奇怪,因为在接口上运行的代码不知道是否允许调用setter。

答案 3 :(得分:1)

如果某些实现只实现接口的某些部分,那么将接口细分为每个实现将完全实现或根本不实现的部分可能是个好主意,然后定义继承所有常见组合的接口他们调整你的例子:

interface IMyReadableInterface
{
    int property { get; }
}
interface IMyFullInterface : IMyReadableInterface
{
    new int property { get; set; }
}

想要支持读写访问的类应该实现IMyFullInterface;那些只想支持读访问的人应该只实现IMyReadableInterface。对于使用C#编写并隐式实现property的任一接口的实现,这种隔离不需要任何额外的工作。在VB中实现property或在C#中显式实现property的代码必须定义property的两个实现 - 一个只读和一个读写,但是这样就是生活。请注意,虽然可以定义一个只有一个setter的IMyWritableInterface,并IMyFullInterface继承IMyReadableInterfaceIMyWritableInterface,但IMyFullInterface仍然需要定义一个它自己的读写属性,当使用显式实现时,必须定义三个属性(我真的不明白为什么C#不能使用只读和只写属性一起认为它们是一个读写属性,但它不能)。

答案 4 :(得分:1)

当然,在某些情况下,您希望接口具有set,然后将其隐藏在某些具体的类中。

我相信下面的代码显示了我们想要完成的工作。即该实现会隐藏设置器,但是任何IMyInterface感知组件都可以访问它。

public static void Main()
{
    var myClass = new MyClass();
    myClass.Property = 123;                 // Error
    ((IMyInterface)myClass).Property = 123; // OK
}

IDisposable.Dispose()所在的shortcuts经常看到的模式基本相同。这是完整性的示例。

public interface IMyInterface
{
    int Property { get; set; }
}

public class MyClass : IMyInterface, IDisposable
{
    public int Property { get; private set; }

    int IMyInterface.Property
    {
        get => Property;
        set => Property = value;
    }
    
    void IDisposable.Dispose() {}
}

键入太多:(

C#在这里对我们没有多大帮助。理想情况下,可以为设置器提供一个明确的接口实现:

// In C# 10 maybe we can do this instead:
public class MyFutureClass : IMyInterface
{
    public int Property { get; IMyInterface.set; }
}

请参阅C#功能建议Explicit Interface Implementation

答案 5 :(得分:0)

界面中没有受保护或私有,一切都是公开的。要么您没有定义任何集合,要么将其用作公共集合。