c# -隐藏继承的成员

Translate

我正在寻找有效隐藏继承成员的方法。我有一个类库,它们从通用基类继承。一些较新的后代类继承了依赖属性,这些依赖属性已经过时,并且在使用时可能会引起混淆智能感知或在视觉设计师中使用这些类。

这些类都是为WPF或Silverlight 2.0编写的所有控件。我知道ICustomTypeDescriptorICustomPropertyProvider,但我可以肯定它们不能在Silverlight中使用。

它不只是功能性问题,而不仅仅是可用性问题。我该怎么办?

更新资料

我真的想隐藏一些属性,这些属性不是我自己的祖先产生的,而且由于我正在设计一个特定的工具,因此我无法使用new操作员。 (我知道,这太荒谬了)

This question and all comments follow the "Attribution Required."

所有的回答

Translate

像迈克尔建议那样覆盖他们以上为了防止人们使用覆盖(sp?)方法,请将其标记为过时的:

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

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

来源
Translate

尽管您无法防止使用这些继承的成员,但您应该能够使用EditorBrowsableAttribute:

Using System.ComponentModel;

[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";

编辑:刚刚在文档注释中看到了这一点,这使其在此目的上毫无用处:

值得注意的是,该属性“不禁止来自同一程序集中的类的成员”。是的,但还不完整。实际上,该属性不会抑制同一解决方案中某个类的成员。

来源
Translate

您可以做的一件事是包含对象,而不是从另一个类扩展。在公开要公开的内容方面,这将为您提供最大的灵活性,但是如果您绝对需要该类型的对象,则不是理想的解决方案(但是您可以从吸气剂中公开该对象)。

从而:

public class MyClass : BaseClass
{
    // Your stuff here
}

成为:

public class MyClass
{
    private BaseClass baseClass;

    public void ExposeThisMethod()
    {
        baseClass.ExposeThisMethod();
    }
}

要么:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
来源
Translate

我认为,最好的方法是考虑组合而不是继承。

或者,您可以创建一个具有所需成员的接口,让派生类实现该接口,然后针对该接口进行编程。

来源
Translate

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

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

使用double类方法摆脱了无法使用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; }
}

现在,valueEnum可用于两个类,但在APIUsageClass类中仅可见该属性。对于想要扩展原始API或以其他方式使用它的人,仍然可以使用APIClass类,而对于想要更简单的东西的人,可以使用APIUsageClass。

最终,我要做的是将APIClass内部化,并且只公开继承的类。

来源
Translate

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

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
来源
Translate

我测试了所有建议的解决方案,它们并没有真正隐藏新成员。

但这确实是:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}

但是在代码隐藏中仍然可以访问,因此也要添加过时属性

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
来源
Translate

您可以使用界面

    public static void Main()
    {
        NoRemoveList<string> testList = ListFactory<string>.NewList();

        testList.Add(" this is ok ");

        // not ok
        //testList.RemoveAt(0);
    }

    public interface NoRemoveList<T>
    {
        T this[int index] { get; }
        int Count { get; }
        void Add(T item);
    }

    public class ListFactory<T>
    {
        private class HiddenList: List<T>, NoRemoveList<T>
        {
            // no access outside
        }

        public static NoRemoveList<T> NewList()
        {
            return new HiddenList();
        }
    }
来源