1

我有一个接口“IBase”,它指定一个可为空的 int。稍后的接口“IDerived”隐藏了可为空的 int 并将其“重新定义”为不可为空。

interface IBase
{
    int? Redefineable { get; set; }
}

interface IDerived : IBase
{
    new int Redefineable { get; set; }
}

实现这些接口的类必须显式实现 hidden 属性,但它是私有的,因此客户端看不到它。

class TheClass : IDerived
{
    public int Redefineable { get; set; }
    int? IBase.Redefineable { get; set; }
}

但是,即使它是私有属性,我仍然可以通过 IBase 接口访问它!

var o = new TheClass();
o.Redefineable = 1; // ok

var hack = o as IBase;
hack.Redefineable = null; // uh!

这似乎是对 C# 访问修饰符的某种违反,但无论哪种方式,这都不是我重新定义(而不仅仅是隐藏)属性的真正想法。从某种意义上说,它按照您的要求进行操作是正确的,得到一个具有可为空的 int 的 IBase 接口,但这对于可能修改错误版本属性的客户端来说是不直观的。

我真正想要的是,如果客户端访问 IBase.Redefinable,那么它的行为就好像它正在访问 IDerived.Redefinable 属性,即 TheClass 的“真实”属性。这样它实际上就被重新定义了,就像在层次结构中一样。

class TheClass : IDerived
{
    public int Redefineable { get; set; }
    int? IBase.Redefineable { 
        get { 
            // redirect to redefined property
            return this.Redefineable; 
        }
        set
        {
            // stop client setting it to null
            if (!value.HasValue)
                throw new InvalidOperationException();

            // redirect to redefined property
            this.Redefineable = value.Value;
        }
    }
}

这就像一个黑客,几乎就像我错过了什么,所以我想问是否有人知道实现可重新定义属性的更好/替代方法?

4

1 回答 1

4

但是,即使它是私有属性,我仍然可以通过 IBase 接口访问它!

它不是私有财产。它只是一个使用显式接口实现的属性。这意味着它通过接口公开,但只能通过接口使用。显式接口实现主要是为了使实现“矛盾”接口变得可行,以及用于“劝阻”(但不禁止)使用某些接口方法。这并不是要给人一种成员根本不存在的印象。

从根本上讲,听起来你不应该在这里使用继承——如果你不想让某些东西能够充当IBase,你不应该继承自IBase.

于 2015-01-26T17:16:32.707 回答