2012-09-19 11 views
6

Mam biblioteki klas z 2 klas publicznych, które dziedziczą z klasy abstrakcyjna. W klasie abstrakcyjnej mam pole chronione, które powinno być dostępne tylko dla dziedziczonych klas. Typ używany w polu to klasa wewnętrzna.Używanie wewnętrznego typu używanego jako chronione pole

Na przykład mam:

internal class MyInternalClass 
{ 
    ... 
} 

public abstract class MyAbstractClass 
{ 
    protected MyInternalClass myField; 
} 

Teraz rozumiem, że to nie będzie działać, ponieważ jeśli jedna z klas związanych z MyAbstract klasie jest przedłużony poza zespołem, dostęp do myField byłoby nielegalne.

Moje pytanie brzmi: w jaki sposób mogę uzyskać rzeczy działające przy zachowaniu wewnętrznej wersji MyInternalClass (nie powinno być dostępne poza zestawem) i pozwalając klasom w zespole na rozszerzenie MyAbstractClass z dostępem do myField?

+4

Czy ta druga klasa ("abstrakcyjna") musi być "publiczna"? –

+0

Tak, to musi być. Dwie klasy, które ją rozszerzają, są publiczne. – zaq

+0

możliwy duplikat [Jak zrobić własność chronioną I wewnętrzną w C#?] (Http: // stackoverflow.com/questions/941104/how-to-make-a-property-protected-and-internal-in-c) – nawfal

Odpowiedz

5

Utwórz publiczny interfejs wymagany przez narzędzia MyAbstractClass i MyInternalClass.

Coś tak więc można mieć to MyInternalClass domyślnie ale wstrzyknąć nowe zachowanie, jeśli potrzebne (na przykład, szydząc):

internal class MyInternalClass : IMyInterface 
{ 
} 

public interface IMyInterface 
{    
} 

public abstract class MyAbstractClass 
{ 
    protected IMyInterface myField; 

    protected MyAbstractClass(IMyInterface required = null) 
    { 
     myField = required ?? new MyInternalClass(); 
    } 
} 
+2

Możesz także zapisać odwołanie do klasy wewnętrznej w polu prywatnym, a następnie udostępnić chronioną własność, podając ją jako publiczną. berło. Ma to tę dodatkową zaletę, że umożliwia dalsze ograniczanie dostępu do klasy wewnętrznej (za pośrednictwem interfejsu) tylko do tego, co jest potrzebne dezodorantom z MyAbstractClass. Daje również elastyczność, jeśli interfejs ten zostanie kiedykolwiek zaimplementowany inaczej (na przykład poprzez dekomponowanie jego funkcjonalności na dwie klasy pomocnicze zamiast na przykład jedną). –

+0

@DanBryant: Very true. Dobry pomysł. –

0

nie można. Jeśli MyAbstractClass pochodzi z zewnętrznej klasy MyInternalClass musi być znany.

Jeśli chcesz pomyśleć o takich rzeczach, projekt może wymagać przerobienia.

0

Utwórz pole myFieldinternal protected.

Musisz również wykonać wewnętrzny obiekt MyAbstractClass . Nie ma możliwości, aby było publiczne, jeśli dziedziczy po wewnętrznej klasie. Jeśli klasa musi być publiczna, to musi istnieć sposób obejścia tego problemu: na przykład utwórz interfejs, który ujawnia funkcjonalność klasyMyInternalClass, której potrzebują klasy dziedziczące.

0

Jesteś w potrzebie słowa kluczowego, które określa chronionego „i” wewnętrzny zamiast chroniony „lub” wewnętrzna. Takie słowo kluczowe nie istnieje (jak w C# 5.0). Mogą go dodać w późniejszych wersjach.

Istnieje wiele wątków na ten temat tutaj. Se na przykład question 5596338.

Ponadto: Teraz mają pochodzić z tego „rozwiązania”:

public abstract class MyAbstractClass 
{ 
    protected class AccessMyFieldHelper 
    { 
     internal MyInternalClass this[MyAbstractClass mac] 
     { 
      get { return mac.myField; } 
      set { mac.myField = value; } 
     } 
    } 
    protected static readonly AccessMyFieldHelper AccessMyField = new AccessMyFieldHelper(); 

    private MyInternalClass myField; 
} 

myField jest teraz private, ale nie jest zabezpieczony dostęp do niego poprzez AccessMyField. Ponieważ jest to indeksator, będziesz musiał użyć kwadratowych nawiasów [].

Co myślisz? Czy można to zrobić piękniej?

Powiązane problemy