Скрытие унаследованных

голоса
34

Я ищу какой - нибудь способ , чтобы эффективно скрыть унаследованные. У меня есть библиотека классов , которые наследуют от общих базовых классов. Некоторые из последних классов - потомков наследуют свойство зависимостей , которые становятся рудиментарными и может быть немного запутанным при использовании IntelliSense или с помощью классов в визуальном конструкторе.

Эти классы являются все элементы управления, которые написаны для компиляции или для WPF или Silverlight 2.0. Я знаю , о ICustomTypeDescriptorи ICustomPropertyProvider, но я почти уверен , те , которые не могут быть использованы в Silverlight.

Это не столько функциональная проблема как проблема юзабилити. Что мне делать?

Обновить

Некоторые из свойств , которые я бы очень хотел , чтобы скрыть прихожу от предков, которые не являются моими и из - за специфический инструментом я проектирование для, я не могу сделать элемент скрывается с newоператором. (Я знаю, это смешно)

Задан 04/08/2008 в 20:13
источник пользователем
На других языках...                            


8 ответов

голоса
32

Перекрыть их как Майкл предлагает , выше и предотвратить людей от использования преодолено методов, помечать их как устаревшие (зр?):

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

Если второй PARM установлена ​​истина, ошибка компиляции будет сгенерирован, если кто-то пытается вызвать этот метод и строку в первом Парм это сообщение. Если parm2 ложен только будет сгенерировано предупреждение компилятора.

Ответил 04/08/2008 в 21:14
источник пользователем

голоса
16

В то время как вы не можете предотвратить использование этих унаследованных членов моего знания, вы должны быть в состоянии скрыть их от IntelliSense , используя EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Просто видел это в комментариях к документации, что делает его своего рода бесполезным для этой цели:

Существует видным отметить, что утверждает, что этот атрибут «не подавляет член из класса в одной сборке». Это правда, но не полная. На самом деле, этот атрибут не подавляет член из класса в том же растворе.

Ответил 04/08/2008 в 20:19
источник пользователем

голоса
13

Одним из возможных, что вы можете сделать, это содержать объект, а не простираться от другого класса. Это даст вам максимальную гибкость с точки зрения воздействия, что вы хотите выставить, но если вы абсолютно необходимо, чтобы объект быть такого типа это не является идеальным решением (однако можно выставить объект из геттер).

Таким образом:

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;
        }
    }
}
Ответил 04/08/2008 в 20:22
источник пользователем

голоса
8

Я думаю, что ты лучше хотя бы хак способа рассмотреть состав, в отличии от наследования.

Или, вы можете создать интерфейс, который имеет элементы, которые вы хотите, имеет производный класс реализовать этот интерфейс и программу против интерфейса.

Ответил 04/08/2008 в 20:19
источник пользователем

голоса
3

Для того, чтобы полностью скрыть и пометить, чтобы не использовать, в том числе IntelliSense, который я считаю, что большинство читателей ожидают ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Ответил 24/06/2013 в 20:50
источник пользователем

голоса
3

Я знаю , что там было несколько ответов на это, и теперь это довольно старый, но самый простой способ сделать это просто объявить их new private.

Рассмотрим пример, я в настоящее время работает над, где у меня есть API, который делает доступным каждый метод в 3-й партии библиотеки DLL. Я должен взять свои методы, но я хочу использовать свойство .Net, вместо и метод «getThisValue» «setThisValue». Таким образом, я построить второй класс, наследуйте первое, сделать свойство, которое использует получить и установить методы, а затем переопределить исходные получить и установить методы, как частные. Они по-прежнему доступны для тех, кто хочет создать что-то другое на них, но если они просто хотят использовать двигатель я здание, то они будут в состоянии использовать свойство вместо методов.

С помощью метода двойного класса избавляется от каких - либо ограничений на невозможность использовать 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. Класс APIClass по-прежнему доступен для людей, которые хотят расширить исходный API или использовать его по-другому, и APIUsageClass доступен для тех, кто хочет что-то более простое.

В конце концов, что я буду делать это делает APIClass Internal, и только выставить свой унаследованный класс.

Ответил 08/12/2010 в 21:54
источник пользователем

голоса
1

Я проверил все из предложенных решений, и они действительно не скрывают новых членов.

Но это одна ДЕЛАЕТ:

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

Но в коде-behide она по-прежнему доступны, так что добавить, а Устаревший атрибут

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Ответил 23/05/2012 в 11:19
источник пользователем

голоса
0

Вы можете использовать интерфейс

    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();
        }
    }
Ответил 13/11/2017 в 00:24
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more