kalıtsal üyeleri gizleme

oy
34

Ben etkin bir miras üyelerini gizlemek için bazı yol arıyorum. Ben ortak baz sınıflardan miras sınıfların bir kütüphane var. Daha yeni soyundan sınıflardan bazıları körelmiş hale gelmiştir ve kullanırken biraz kafa karıştırıcı olabilir bağımlılık özelliklerini devralır IntelliSense'i veya görsel tasarımcı sınıfları kullanarak.

Bu sınıflar WPF veya Silverlight 2.0 ya derlenmiş olması yazılır tüm kontrollerin. Bilmem ICustomTypeDescriptorve ICustomPropertyProvider, ancak bu Silverlight kullanılamaz olduğuna eminim.

O kadar değil bir kullanılabilirlik sorunu olarak işlevsel bir mesele. Ne yapmalıyım?

Güncelleştirme

Gerçekten benim değil atalarından ve çünkü için tasarlıyorum belirli aracın gelip gizlemek istiyorum özelliklerin bazıları, beraber gizleme üyesini yapamaz newoperatörü. (Biliyorum, bu çok saçma)

Oluştur 04/08/2008 saat 20:13
kaynak kullanıcı
Diğer dillerde...                            


8 cevaplar

oy
32

Michael Önerdi gibi onları geçersiz kıl yukarıda ve geçersiz kullanmasını millet önlemek için yöntemler olarak eskimiş işaretlemek (sp?):

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

İkinci parm true ayarlanırsa, bir derleyici hatası herkes bu yöntem ve ilk parm dizeyi aramaya çalışırsa mesajdır oluşturulur. parm2 false ise sadece derleyici uyarısı oluşturulur.

Cevap 04/08/2008 saat 21:14
kaynak kullanıcı

oy
16

Benim kadarıyla bu kalıtsal üyelerin kullanımını önlemek edemesek de, kullandığınız IntelliSense bunları gizlemek mümkün olmalıdır EditorBrowsableAttribute :

Using System.ComponentModel;

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

Düzenleme: Sadece bu amaçla bu tür yararsız hale getiren dokümantasyon yorumlarda gördüm:

Bu özellik "aynı derlemede bir sınıftan üye bastırmak değil" belirten önemli bir not var. Bu doğru ama tam değil. Aslında, nitelik aynı çözümde bir sınıftan üye bastırmak değil.

Cevap 04/08/2008 saat 20:19
kaynak kullanıcı

oy
13

Yapabileceğiniz potansiyel bir şey nesnesi ihtiva ziyade başka sınıftan uzatmak olduğunu. Bu sergilemek istediklerini açığa açısından en fazla esneklik verir, ama kesinlikle ideal çözüm olmadığını tipte nesne gerekiyorsa (ancak bir gaz giderici nesneyi maruz bırakabilir).

Böylece:

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

Oluyor:

public class MyClass
{
    private BaseClass baseClass;

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

Veya:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Cevap 04/08/2008 saat 20:22
kaynak kullanıcı

oy
8

Seni en iyi azından hackish yolu miras aksine kompozisyonu dikkate almaktır olduğunu düşünüyorum.

Veya, istediğiniz üyeye sahip bir arayüz oluşturabilir, türetilmiş sınıf arayüzüne karşı arayüzü ve programı uygulamak gerekir.

Cevap 04/08/2008 saat 20:19
kaynak kullanıcı

oy
3

Tamamen gizlemek ve için çok okuyucunun beklediğiniz olduğuna inanıyoruz intellisense dahil kullanmamayı işaretlemek ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Cevap 24/06/2013 saat 20:50
kaynak kullanıcı

oy
3

Bunun için birkaç cevaplar geçtiğini biliyorum ve şimdi oldukça eski, ama bunu yapmak için en basit yöntem gibi onları beyan edilir new private.

Bir 3. parti DLL mevcut her yöntemi kılan bir API vardır nerede şu anda, üzerinde çalışıyorum bir örneği düşünün. Ben onların yöntemlerini almak zorunda, ama bunun yerine bir "getThisValue" ve "setThisValue" yönteminin, bir .Net özelliğini kullanmak istiyorum. Yani, alma ve kurma yöntemleri kullanan bir özellik yapmak, ilk devralır ve sonra özgün get ve özel olarak ayarlanmış yöntemler geçersiz, ikinci sınıf oluşturmak. Onlar hala üzerlerinde farklı bir şey inşa etmek isteyen herkes için kullanılabilir, ama onlar sadece ben inşa ediyorum motoru kullanmak istiyorsanız, o zaman yerine yöntemlerin özelliklerini kullanmak mümkün olacak.

Çift sınıf yöntemi kullanarak kullanmak mümkün olduğu herhangi bir kısıtlama kurtulur newüyelerini gizlemek için deklarasyon. Sadece kullanamazsınız overrideüyeleri sanal olarak işaretlenen eğer.

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

Şimdi valueEnum hem sınıflar için kullanılabilir, ancak sadece mülkiyet APIUsageClass sınıfında görülebilir. APIClass sınıfı hala orijinal API uzatmak veya farklı bir şekilde kullanmak isteyenler için kullanılabilir ve APIUsageClass daha basit bir şey isteyenler için kullanılabilir.

Sonuçta, ne yapıyor olacağım APIClass Dahili yapma ve sadece benim miras sınıfı maruz olduğunu.

Cevap 08/12/2010 saat 21:54
kaynak kullanıcı

oy
1

Ben önerilen çözümlerin hepsi test edilmiş ve onlar gerçekten yeni üyeler gizlemek değildir.

Ama bu YAPAR:

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

Ama kod Behide içinde hala erişilebilir, böylece hem Eski Özellik eklemek

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Cevap 23/05/2012 saat 11:19
kaynak kullanıcı

oy
0

Sen bir arabirim kullanabilirsiniz

    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();
        }
    }
Cevap 13/11/2017 saat 00:24
kaynak kullanıcı

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