2016-08-09 3 views
0

Ich möchte den Zugriff auf Methoden einschränken, abhängig vom übergebenen Typ. In meiner speziellen Situation entwickle ich einen UDP- "Manager", wenn Sie so wollen.Dynamischer Methodenzugriffsmodifikator

Ich möchte meine UDPManager für verschiedene Dinge verwendet werden. Zum Beispiel könnte ich 1 UDPManager für die Kommunikation zwischen Client und Server haben, und ein anderes UDPManager, um die Kommunikation zwischen Server und einem anderen Server zu behandeln.

Ich habe eine enum definiert, die den Typ UDPManager angibt. So zum Beispiel, ManagerType.A = 1 und ... ManagerType.B = 2

Die UDPManager hat bestimmte Ereignisse, die abonniert werden können, und ich will sie nicht zur Verfügung, wenn diese Ereignisse nicht relevant sind, angesichts der Art des UDPManager. Hier

ist ein Beispiel einer Klasse

public class Something 
{ 
    public int SomethingsType { get; set; } 
    public void A() { } 
    public void B() { } 
} 

Wie kann ich es so machen, dass, wenn SomethingsType == MessageType.A, dann MessageType.B nicht verfügbar ist (dh es ist privat)?

Für weitere Klarheit, wenn ich schreibe:

Something something = new Something(); 
someting.SomethingsType = 1 

I verfügbar sein nicht something.B() wollen.

UPDATE

Ich entschuldige mich runtime für die Erwähnung. Was ich meine, ist, dass ich die genannte Methode (B) nicht verfügbar habe, wenn SomethingsTypeA ist.

+1

ist nicht möglich. Sie können Methoden immer mit Reflektion aufrufen, auch wenn sie privat sind. – Steve

+0

Das Zeug wird vom Compiler erzwungen. Es ist zur Laufzeit bedeutungslos. Was bedeutet "zur Zeit nicht verfügbar (dh privat)" zur Laufzeit *? Was erwarten Sie, wenn der Compiler Code kompiliert, der 'something.B()' aufruft (weil er in der Quelldatei öffentlich ist), und später wird die Methode plötzlich privat? –

+3

Implementieren Sie 'SomethingA',' SomethingB' etc. Verwenden Sie dann eine Factory-Methode mit dem Namen 'ManagerType'. – mxmissile

Antwort

1

Schnittstellen zur Rettung:

public interface IUdpManagerA 
{ 
    void A(); 
} 

public interface IUdpManagerB 
{ 
    void B(); 
} 

public class UdpManager : IUdpManagerA, IUdpManagerB 
{ 
    public void A() { } 
    public void B() { }    
} 

public class UdpManagerFactory 
{ 
    private UdpManager Create() => new UdpManager(); 
    public IUdpManagerA CreateOfA() => Create(); 
    public IUdpManagerB CreateOfB() => Create(); 
} 

UdpManagerFactory factory = new UdpManagerFactory(); 
IUdpManagerA a = factory.CreateOfA(); 
IUdpManagerB b = factory.CreateOfB(); 

Schnittstellen sind ein mächtiges Werkzeug bestimmte Mitglieder zu veröffentlichen während andere versteckt bleiben können.

Während Sie vielleicht ja sagen, aber man kann immer IUdpManagerA-IUdpManagerB gegossen und umgekehrt Zugriff auf versteckte Mitglieder zu gewinnen, und meine Antwort ist ** dies ist nicht sicher, weil es keinen Anhaltspunkt ist, dass IUdpManagerA implementiert auch IUdpManagerB und umgekehrt.

Oh, und ich vergaß zu erwähnen, dass Sie die ManagerType Aufzählung wegwerfen sollte, denn mit Schnittstellen können Sie jederzeit überprüfen, ob eine bestimmte Instanz ist ein oder B:

object instance = factory.CreateA(); 

if(instance is IUdpManagerA) 
{ 
} 

if(instance is IUdpManagerB) 
{ 
} 

oder mit as operator:

object instance = factory.CreateA(); 
IUdpManagerA a = instance as IUdpManagerA; 
IUdpManagerB b = instance as IUdpManagerB; 

if(a != null) 
{ 
} 
else if(b != null) 
{ 
} 
+0

Vielen Dank! Das ist toll. Wie heißt dieses Designmuster? – pookie

+0

@pookie Factory-Methode https://en.wikipedia.org/wiki/Factory_method_pattern –

+0

@MatiasFidermraizer Großartig, danke! – pookie

0

Dies ist ein extreme einfache Version eines Verfahrens Fabrik Build basiert eines ENUM:

public enum ManagerType 
    { 
     A,B 
    } 

    public abstract class UDPManager 
    { 

    } 

    public class SomethingA : UDPManager 
    { 
     public void A() 
     {} 
    } 

    public class SomethingB : UDPManager 
    { 
     public void B() 
     {} 
    } 

    public class UdpManagerFactory 
    { 
     public UDPManager Build(ManagerType type) 
     { 
      if (type == ManagerType.A) 
       return new SomethingA(); 

      if(type == ManagerType.B) 
       return new SomethingB(); 

      throw new Exception("type not found"); 
     } 
    } 
+0

Vielen Dank! Ich denke, dass dieser Weg auch funktionieren würde, aber finde, dass die Antwort von Matias passender ist. – pookie