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

发布于 2024-11-04 04:07:25 字数 497 浏览 2 评论 0原文

大家好...

如果我有以下接口:

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

以及以下实现:

class MyClass : IMyInterface
{
// anything
}

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

使用抽象类很容易做到:

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

然后我只能在实现上面抽象类的类中设置属性...

Greetings everyone...

If I have the following interface:

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

And the following implementation:

class MyClass : IMyInterface
{
// anything
}

How can I hide the set method of property from the instances of MyClass... In other words, I don't want the set method of property to be public, is that possible?

It would be easy to do with abstract class:

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

Then I could only set the property within the class that implements the abstract class above...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

东风软 2024-11-11 04:07:25

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

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

Don't have the set in the interface to begin with. You can still implement it as private.

You can't "hide" it, it's part of the contract. If you don't want it to be part of the contract, don't define it.

孤星 2024-11-11 04:07:25

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

interface IMyInterface
{ 
   int property { get; }
}

然后您可以像这样实现该类:

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

If you use the following interface the set method will be unavailable when classes are manipulated via the interface:

interface IMyInterface
{ 
   int property { get; }
}

You could then implement the class like this:

class MyClass : IMyInterface
{
  int property { get; protected set; }
}
柠栀 2024-11-11 04:07:25

如果某些实现仅实现接口的某些部分,那么最好将接口细分为每个实现将完全实现或根本不实现的部分,然后定义继承它们的所有常见组合的接口。调整您的示例:

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 继承 IMyReadableInterfaceIMyWritableInterfaceIMyFullInterface 仍然必须定义自己的读写属性,并且当使用显式实现时,必须定义 三个 属性(我真的不明白为什么 C# 不能同时使用只读和只写属性,因为它们是读写属性,但事实并非如此)。

If some implementations will only implement some parts of an interface, it may be a good idea to subdivide the interface into the parts which each implementation will either implement completely or not at all, and then define interfaces which inherit all the common combinations of them. Adapting your example:

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

Classes which want to support read-write access should implement IMyFullInterface; those which want to only support read access should only implement IMyReadableInterface. This segregation will not require any extra work for implementations of either interface which are written in C# and implement property implicitly. Code which implements property in VB, or explicitly implements property in C#, will have to define two implementations of property--a read-only one and a read-write one, but such is life. Note that while one could define an IMyWritableInterface which just had a setter, and have IMyFullInterface inherit both IMyReadableInterface and IMyWritableInterface, IMyFullInterface would still have to define a read-write property of its own, and when using explicit implementation one would then have to define three properties (I really don't understand why C# can't use a read-only and write-only property together as thought they were a read-write property, but it can't).

刘备忘录 2024-11-11 04:07:25

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

Assuming you need the setter to be part of the interface but for some reason it does not make sense for it to be used on a particular implementer (in this case MyClass) you can always throw an exception in the setter (such as an InvalidOperationException). This will not protect you at compile time, only at run time. It is a bit strange though, as code that operates on the interface has no idea whether calling the setter is allowed.

删除会话 2024-11-11 04:07:25

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

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

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

这基本上与您经常在 IDisposable.Dispose() 中看到的模式相同,其中您有一个 显式接口实现。这是一个完整性示例。

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# 在这里对我们没有多大帮助。理想情况下,可以为 setter 提供显式接口实现:

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

请参阅 C# 功能提案 此处

There are certainly cases where you want the interface to have a set and then hide it in some concrete class.

I believe the code below shows what we want to accomplish. I.e. the implementation hides the setter, but any IMyInterface aware component will have access to it.

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

It's basically the same pattern you often see for IDisposable.Dispose() where you have an Explicit Interface Implementation. Here's an example for completeness.

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() {}
}

Too much typing :(

C# doesn't help us much here. Ideally, it would be possible to have an explicit interface implementation for the setter:

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

See C# feature proposal here.

时光礼记 2024-11-11 04:07:25

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

There is no protected or private in interface, everything is public. Either you don't define any set or use it as public.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文