pookie pookie - 3 months ago 14
C# Question

Dynamic method access modifier

I would like to restrict access to methods, depending on the type passed in. In my particular situation, I am developing a UDP "manager" if you will.

I want my

UDPManager
to be used for different things. For example, I might have 1
UDPManager
for the communications between client and server, and another
UDPManager
to handle the communications between server and another server.

I have defined an
enum
which specifies the type of
UDPManager
. So for example,
ManagerType.A = 1
and...
ManagerType.B = 2


The
UDPManager
has certain events that can be subscribed to and I do not want them available if these events are not relevant, given the type of
UDPManager
.

Here is an example of a class

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


How can I make it so that if
SomethingsType == MessageType.A
, then
MessageType.B
is not available (ie it is private)?

For further clarity, if I type:

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


I do not want
something.B()
to be available.

UPDATE

I apologise for mentioning
runtime
. What I mean is, I do not want said method (
B
) available if said
SomethingsType
is
A
.

Answer

Interfaces to the rescue:

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

Interfaces are a powerful tool to publish certain members while others can remain hidden.

While you might say yeah, but you can always cast IUdpManagerA to IUdpManagerB and vice versa to gain access to hidden members, and my answer is **this isn't safe because there's no clue that IUdpManagerA also implements IUdpManagerB and vice versa.

Oh, and I forgot to mention that you should throw away the ManagerType enumeration, because with interfaces you can always check if a given instance is A or B:

object instance = factory.CreateA();

if(instance is IUdpManagerA)
{
}

if(instance is IUdpManagerB)
{
}

or using as operator:

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

if(a != null)
{
} 
else if(b != null)
{
}
Comments