隐藏继承的成员

Moj*_*ter 40 c# polymorphism silverlight wpf dependency-properties

我正在寻找一些有效隐藏继承成员的方法.我有一个继承自公共基类的类库.一些较新的后代类继承了依赖属性,这些属性已成为残留,在使用IntelliSense或在可视化设计器中使用类时可能会有点混乱.

这些类是为WPF或Silverlight 2.0编写的所有控件.我知道ICustomTypeDescriptorICustomPropertyProvider,但我很确定那些不能在Silverlight中使用.

它不是可用性问题的功能问题.我该怎么办?

更新

我真正想隐藏的一些属性来自不属于我自己的祖先,而且由于我正在设计的特定工具,我不能将成员隐藏在new操作员身上.(我知道,这太荒谬了)

car*_*den 35

上面的迈克尔建议一样覆盖它们并防止人们使用被覆盖的(sp?)方法,将它们标记为过时:

[Obsolete("These are not supported in this class.", true)]
public override  void dontcallmeanymore()
{
}
Run Code Online (Sandbox Code Playgroud)

如果第二个parm设置为true,则如果有人尝试调用该方法并且第一个parm中的字符串是消息,则将生成编译器错误.如果parm2为false,则仅生成编译器警告.

  • @JamesM 大声笑我做到了,这就是为什么我回答了您最初的问题并指出为什么密封没有执行相同的任务。然后你注意到 `Obselete` 只给出一个警告,这是不正确的,因为 `true` 的第二个参数导致编译器错误而不是警告 - 正如你直接评论的答案明确指出的那样。如果我误解了你,我欢迎澄清。这是 [MSDN 源代码](https://msdn.microsoft.com/en-us/library/22kk2b44(v=vs.90).aspx) (2认同)

Mic*_*tum 16

虽然您无法阻止我对这些继承成员的使用,但您应该能够使用EditorBrowsableAttribute将它们从IntelliSense中隐藏起来:

Using System.ComponentModel;

[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";
Run Code Online (Sandbox Code Playgroud)

编辑:刚刚在文档注释中看到了这一点,这使得它有点用于此目的:

有一个突出的说明,声明此属性"不会抑制同一程序集中的类的成员".这是事实但不完整.实际上,该属性不会抑制同一解决方案中的类的成员.


Mik*_*one 13

您可以做的一件事是包含对象而不是从另一个类扩展.这将使您在暴露要暴露的内容方面具有最大的灵活性,但如果您绝对需要该类型的对象,则它不是理想的解决方案(但是您可以从getter中公开该对象).

从而:

public class MyClass : BaseClass
{
    // Your stuff here
}
Run Code Online (Sandbox Code Playgroud)

变为:

public class MyClass
{
    private BaseClass baseClass;

    public void ExposeThisMethod()
    {
        baseClass.ExposeThisMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

要么:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Kar*_*uin 8

我认为你最好的最简单方法是考虑构成而不是继承.

或者,您可以创建一个包含所需成员的接口,让派生类实现该接口,并针对该接口进行编程.


Nat*_*ler 5

我知道对此有几个答案,而且现在已经很旧了,但最简单的方法是将它们声明为new private.

考虑我当前正在处理的一个示例,其中我有一个 API,可以使用第 3 方 DLL 中的每个方法。我必须采用他们的方法,但我想使用 .Net 属性,而不是“getThisValue”和“setThisValue”方法。因此,我构建第二个类,继承第一个类,创建一个使用 get 和 set 方法的属性,然后将原始 get 和 set 方法重写为私有方法。任何想要在其上构建不同内容的人仍然可以使用它们,但如果他们只想使用我正在构建的引擎,那么他们将能够使用属性而不是方法。

使用双类方法可以消除无法使用new声明隐藏成员的任何限制。override如果成员被标记为虚拟,您就无法使用。

public class APIClass
{
    private static const string DllName = "external.dll";

    [DllImport(DllName)]
    public extern unsafe uint external_setSomething(int x, uint y);

    [DllImport(DllName)]
    public extern unsafe uint external_getSomething(int x, uint* y);

    public enum valueEnum
    {
        On = 0x01000000;
        Off = 0x00000000;
        OnWithOptions = 0x01010000;
        OffWithOptions = 0x00010000;
    }
}

public class APIUsageClass : APIClass
{
    public int Identifier;
    private APIClass m_internalInstance = new APIClass();

    public valueEnum Something
    {
        get
        {
            unsafe
            {
                valueEnum y;
                fixed (valueEnum* yPtr = &y)
                {
                    m_internalInstance.external_getSomething(Identifier, yPtr);
                }
                return y;
            }
        }
        set
        {
            m_internalInstance.external_setSomething(Identifier, value);
        }
    }

    new private uint external_setSomething(int x, float y) { return 0; }
    new private unsafe uint external_getSomething(int x, float* y) { return 0; }
}
Run Code Online (Sandbox Code Playgroud)

现在 valueEnum 对两个类都可用,但只有该属性在 APIUsageClass 类中可见。APIClass 类仍然适用于那些想要扩展原始 API 或以不同方式使用它的人,而 APIUsageClass 则适用于那些想要更简单的东西的人。

最终,我要做的就是使 APIClass 成为内部的,并且只公开我继承的类。


Rob*_*ert 5

完全隐藏并标记不使用,包括智能感知,我相信这是大多数读者所期望的

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Run Code Online (Sandbox Code Playgroud)