Вопрос

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

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

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

Обновить

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

Это было полезно?

Решение

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

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

Если для второго параметра установлено значение true, будет сгенерирована ошибка компилятора, если кто-либо попытается вызвать этот метод, а строка в первом параметре является сообщением.Если parm2 имеет значение false, будет сгенерировано только предупреждение компилятора.

Другие советы

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

Using System.ComponentModel;

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

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

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

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

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

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;
        }
    }
}

Я думаю, что вам лучше всего использовать наименее хакерский способ - рассматривать композицию как противоположность наследованию.

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

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

В конечном счете, то, что я буду делать, это делать APIClass внутренним и предоставлять доступ только к моему унаследованному классу.

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

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

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

Но этот ДЕЛАЕТ:

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

Но в code-behide он все еще доступен, поэтому добавьте также устаревший атрибут

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

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

    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();
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top