我有两个班级,[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
答案 0 :(得分:1)
我认为我将过多的实现细节委托给子类,因此一种可能的解决方案是使用模板方法设计模式,使用三种不同的方法进行合作:
这样,我得到以下调用堆栈:
我测试了它的确有效,所以这里有代码:
核心组装:
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
}