简体   繁体   中英

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 .

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)
{
}

This is an extreme simple version of a factory build method based of an 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");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM