2012-12-19 14 views
10

Czy możemy utworzyć własność klasy widocznej dla publiczności, ale może ona być modyfikowana tylko przez określone klasy?jak zaimplementować selektywną widoczność właściwości w języku C#?

np

// this is the property holder 
public class Child 
{ 
    public bool IsBeaten { get; set;} 
} 

// this is the modifier which can set the property of Child instance 
public class Father 
{ 
    public void BeatChild(Child c) 
    { 
     c.IsBeaten = true; // should be no exception 
    } 
} 

// this is the observer which can get the property but cannot set. 
public class Cat 
{ 
    // I want this method always return false. 
    public bool TryBeatChild(Child c) 
    { 
     try 
     { 
      c.IsBeaten = true; 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 

    // shoud be ok 
    public void WatchChild(Child c) 
    { 
     if(c.IsBeaten) 
     { 
      this.Laugh(); 
     } 
    } 

    private void Laugh(){} 
} 

Dziecko jest klasą danych
nadrzędna jest klasa, która może modyfikować dane,
Cat jest klasa, która może odczytać tylko dane.

Czy istnieje sposób wdrożenia takiej kontroli dostępu przy użyciu właściwości w języku C#?

Odpowiedz

4

Zamiast wystawiania wewnętrzny stan klasie dziecko może podać metodę Zamiast:

class Child { 
    public bool IsBeaten { get; private set; } 

    public void Beat(Father beater) { 
    IsBeaten = true; 
    } 
} 

class Father { 
    public void BeatChild(Child child) { 
    child.Beat(this); 
    } 
} 

Następnie kot nie może pokonać dziecko:

class Cat { 
    public void BeatChild(Child child) { 
    child.Beat(this); // Does not compile! 
    } 
} 

Jeśli inni ludzie muszą być w stanie pokonać dziecko, zdefiniować interfejs, który mogą zaimplementować:

interface IChildBeater { } 

Następnie niech zaimplementują to:

class Child { 
    public bool IsBeaten { get; private set; } 

    public void Beat(IChildBeater beater) { 
    IsBeaten = true; 
    } 
} 

class Mother : IChildBeater { ... } 

class Father : IChildBeater { ... } 

class BullyFromDownTheStreet : IChildBeater { ... } 
+0

thx. ale co, jeśli nie możemy zdefiniować lub zmienić _Beatera? tj. kod _Child_ to kod klienta, podczas gdy _Beater_ może być pakietem innej firmy, który implementuje niektóre funkcje, takie jak serializacja i może być później zastąpiony przez innego liberała? – lowatt

+0

W takim przypadku prawdopodobnie niewiele można zrobić. Jeśli autor Beater określi interakcję między nim a dzieckiem, prawdopodobnie będziesz musiał zaufać stronom trzecim, które postąpią słusznie. Jest to raczej problem związany z edukacją i dokumentacją niż coś, co można rozwiązać za pomocą kodu. –

2

Zazwyczaj uzyskuje się to za pomocą oddzielnych złożeń i InternalsVisibleToAttribute. Po zaznaczeniu klas set z bieżącym zestawem będą miały do ​​niego dostęp. Używając tego atrybutu, możesz dać dostęp do niego innym konkretnym zespołom. Pamiętaj, że używając Reflection zawsze będzie można edytować.

Powiązane problemy