2016-08-09 5 views
0

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

Я хочу, чтобы мой UDPManager использовался для разных вещей. Например, у меня может быть 1 UDPManager для связи между клиентом и сервером и еще один UDPManager для обработки сообщений между сервером и другим сервером.

Я определил enum, который определяет тип UDPManager. Так, например, ManagerType.A = 1 и ... ManagerType.B = 2

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

Вот пример класса

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

Как я могу сделать это так, что если SomethingsType == MessageType.A, то MessageType.B не доступна (т.е. частный)?

Для большей ясности, если я типа:

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

Я не хочу something.B() быть доступны.

UPDATE

Прошу прощения за упоминание runtime. Я имею в виду, что я не хочу, чтобы указанный способ (B) был доступен, если указан SomethingsType - A.

+1

его невозможно. вы всегда можете ссылаться на методы с отражением, даже если они являются частными. – Steve

+0

Этот материал применяется компилятором. Это не имеет смысла во время выполнения. В вашем сознании, что «недоступно (т.е. оно является частным)» означает * во время выполнения *? Что вы ожидаете, когда компилятор компилирует код, который вызывает 'something.B()' (потому что он общедоступен в исходном файле), а позже метод внезапно становится закрытым? –

+3

Внесите 'SomethingA',' SomethingB' и т. Д. Затем используйте фабричный метод, заданный 'ManagerType'. – mxmissile

ответ

1

Интерфейсы для спасения:

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(); 

Интерфейсы являются мощным инструментом для публикации отдельных членов в то время как другие могут оставаться скрытыми.

В то время как вы могли бы сказать да, но вы всегда можете бросить IUdpManagerA в IUdpManagerB и наоборот, чтобы получить доступ к скрытым членам, и мой ответ ** это не безопасно, потому что нет никакой подсказки, что IUdpManagerA также реализует IUdpManagerB и наоборот.

О, и я забыл упомянуть, что вы должны выбросить ManagerType перечисление, потому что с интерфейсами вы всегда можете проверить, является ли данный экземпляр A или Аргументы B:

object instance = factory.CreateA(); 

if(instance is IUdpManagerA) 
{ 
} 

if(instance is IUdpManagerB) 
{ 
} 

или с использованием as Оператор:

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

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

Спасибо! Отлично. Как называется этот шаблон дизайна? – pookie

+0

@pookie Фабричный метод https://en.wikipedia.org/wiki/Factory_method_pattern –

+0

@MatiasFidermraizer Отлично, спасибо! – pookie

0

Это экстремальный простой вариант метода завод сборки на основе из перечисления:

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

Спасибо! Я думаю, что так будет работать, но чувствую, что ответ Матиаса более подходит. – pookie

Смежные вопросы