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

голоса
34

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

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

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

Обновить

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

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


9 ответов

голоса
16

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

Using System.ComponentModel;

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

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

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

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

голоса
8

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

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

Ответил 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
источник пользователем

голоса
32

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

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

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

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

голоса
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
источник пользователем

голоса
3

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

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

голоса
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
источник пользователем

голоса
0

Хотя ясно, что было сказано выше, что это не возможно в C #, чтобы изменить модификаторы доступа на унаследованных методов и свойств, я преодолел эту проблему через своего рода «фальшивый наследования», используя неявное приведение.

Пример:

public class A
{
      int var1;
      int var2;

      public A(int var1, int var2)
      {
            this.var1 = var1;
            this.var2 = var2;
      }
      public void Method1(int i)
      {
            var1 = i;
      }
      public int Method2()
      {
            return var1+var2;
      }
}

Теперь предположим , вы хотите , class Bчтобы наследовать от class A, но хотите изменить некоторые доступность или даже изменить method1 полностью

public class B
{
      private A parent;

      public B(int var1, int var2)
      {
            parent = new A(var1, var2);
      } 

      int var1 
      {
            get {return this.parent.var1;}
      }
      int var2 
      {
            get {return this.parent.var2;}
            set {this.parent.var2 = value;}
      }

      public Method1(int i)
      {
            this.parent.Method1(i*i);
      }
      private Method2()
      {
            this.parent.Method2();
      }


      public static implicit operator A(B b)
      {
            return b.parent;
      }
}

Включив неявное приведение в конце концов, это позволяет рассматривать Bобъекты как Aс , когда нам нужно. Она также может быть полезна для определения неявных отлиты из A->B.

Самый большой недостаток этого подхода заключается в том, что вам нужно переписать каждый метод / свойство, которое вы собираетесь «наследовать». Там, наверное, даже больше недостатков этого подхода, но я хотел бы использовать его в качестве своего рода «фальшивого наследования».

Примечание:

Хотя это позволяет изменять доступность publicсвойств, это не решает проблему создания protectedсвойств общественности.

Ответил 11/10/2019 в 18:30
источник пользователем

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