Make方法只能访问其他类

时间:2017-01-11 13:53:38

标签: c# access-modifiers

我有两个班级,[HttpPost] public ActionResult Example(String value+count ) { string a = value+count; //a is null ...... } Sensor。它们被"插入"通道中的传感器(即,使用Channel实例设置Sensor的{​​{1}}属性。然后,当您使用非空传感器在Channel中呼叫Sensor时,系统会通知AddSamples的订阅者:

Channel

我想要实现的是一种在内部传递这些示例的方法,而不必创建公开的Sensor.WhenNewSamples。当然,它也应该与其他程序集中定义的子类一起使用,因为public abstract class Channel { public Sensor Sensor { get; set; } public abstract void AddSamples(IEnumerable<double> samples) } public abstract class Sensor { public abstract IObservable<double> WhenNewSamples { get; } internal abstract void AddSamples(IEnumerable<double> samples); } Sensor.AddSamples是抽象的,并在域模型库中定义。

更新:

以下实现没问题,但它没有编译,因为Sensor是内部的,派生类在其他程序集中:

Channel

2 个答案:

答案 0 :(得分:1)

我认为我将过多的实现细节委托给子类,因此一种可能的解决方案是使用模板方法设计模式,使用三种不同的方法进行合作:

  • 一个是模板方法:一个应该由子类充实的受保护的抽象方法;
  • 其他是实现“业务逻辑”的内部非虚方法:从内部方法调用到受保护的模板方法;
  • 某个“外部”类中的公共方法,将调用转发给“内部”类中的内部方法。

这样,我得到以下调用堆栈:

  1. 我在客户端程序集中定义的外部子类中调用了一个公共方法;
  2. 该方法实际上是在核心程序集的基类中实现的,并且在核心程序集中也从内部基类调用内部方法;
  3. 客户端基类中的内部方法调用受保护的模板方法,该方法由客户端程序集中的内部子类实现。
  4. 我测试了它的确有效,所以这里有代码:

    核心组装:

    public abstract class Channel
    {
        // inner class is a property of outer class
        public Sensor Sensor { get; set; }
    
        // Public method in outer class calls internal method in inner class
        public void AddSamples(IEnumerable<double> samples)
        {
            Sensor?.AddSamplesInternal(samples);
        }
    }
    
    public abstract class Sensor
    {
        // domain specific property exposing the effects of template method
        public abstract IObservable<double> WhenNewSamples { get; }
    
        // internal method forwards the call to a protected abstract "template" method
        internal void AddSamplesInternal(IEnumerable<double> samples)
        {
            AddSamplesProtected(samples);
        }
    
        // protected abstract method to be implemented by subclasses
        protected abstract void AddSamplesProtected(IEnumerable<double> samples);
    }
    

    客户端程序集:

    using System.Linq;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;
    
    public class ConcreteChannel : Channel
    {
        // no need to do anything - public method defined in base class
    }
    
    public class ConcreteSensor : Sensor
    {
        // domain specific implementation
        public override IObservable<double> WhenNewSamples
        {
            get { return _subject.AsObservable(); }
        }
        Subject<double> _subject = new Subject<double>();
    
        // template method implemented locally, but called from business logic present in core lib
        protected override void AddSamplesProtected(IEnumerable<double> samples)
        {
            samples.ToList().ForEach(sample => _subject.OnNext(sample));
        }
    }
    

    示例程序:

    class Program
    {
        static void Main(string[] args)
        {
            ConcreteChannel channel = new ConcreteChannel();
            ConcreteSensor sensor = new ConcreteSensor();
    
            // "plugging" a sensor into a channel
            channel.Sensor = sensor;
    
            // "sensor" works as a data source for other client code
            sensor.WhenNewSamples.Subscribe(Console.WriteLine);
    
            // channel works as a data target for data coming from some server class
            channel.AddSamples(Enumerable.Range(0, 10).Select(Convert.ToDouble));
        }
    }
    

    输出:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

答案 1 :(得分:0)

您可以使用嵌套类的功能来访问类的私有/受保护成员:

abstract class A
{
    protected abstract void SomeMethod();
}
abstract class B { }

class AA : A
{
    public class BB : B
    {
        public void Test(AA a) => a.SomeMethod(); // no problem to access it here
    }
    protected override void SomeMethod() { } // is not public
}