【问题标题】:Dynamic method access modifier动态方法访问修饰符
【发布时间】:2016-08-09 19:39:11
【问题描述】:

我想根据传入的类型限制对方法的访问。在我的特殊情况下,如果您愿意,我正在开发一个 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() 可用。

更新

我很抱歉提到runtime。我的意思是,如果说SomethingsTypeA,我不想说方法(B)可用。

【问题讨论】:

  • 不可能。即使它是私有的,您也可以随时使用反射调用方法。
  • 实现SomethingASomethingB等。然后使用给定ManagerType的工厂方法。
  • 不就是继承存在的原因吗?经理是父母,经理A,经理B是孩子吗?
  • 没有。如果您想对自己造成恶作剧,只需拿起一把锤子并用它敲打自己的头部即可。它更快,并且保证可以工作。
  • 听起来像教科书XY problem。您需要重新考虑 API 的基本结构。

标签: c# access-modifiers


【解决方案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)
{
}

【讨论】:

【解决方案2】:

这是一个基于枚举的工厂构建方法的extreme简单版本:

    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");
        }
    }

【讨论】:

  • 谢谢!我觉得这种方式也行,但觉得Matias的回答更合适。
猜你喜欢
  • 2014-09-08
  • 2015-12-24
  • 2022-11-18
  • 2014-12-29
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 2014-11-03
  • 2011-04-13
相关资源
最近更新 更多