我有一个C#Windows Phone 8应用程序,对于拥有它的手机,使用Compass传感器来实现特定功能。我想修改课程,以便它可以在没有指南针传感器的手机上工作。我不想在 if(_compass!= null)语句中包含对Compass对象的每次调用。我想我可以创建一个虚拟的 Compass 类,其中包含Compass方法和属性的存根,如果手机没有指南针,则创建它的实例而不是Compass,但是我&#39 ; m遇到Compass类的抽象基类问题,名为 SensorBase 。无论我做什么,我都会收到编译时错误:
Error 1 The type 'Microsoft.Devices.Sensors.SensorBase<TSensorReading>' has no constructors defined
Compass类我尝试模拟可以从SensorBase继承而不会出现此错误。我从Sensors元数据文件中获取了Compass类的确切声明行,并在将类名更改为 CompassDummy 后将其插入到我的虚拟类中,但仍然出现错误。
我的猜测是Compass类可以继承SensorBase而我的虚拟类不能继承,因为它与SensorBase位于同一个程序集中。也许SensorBase的构造函数标记为 internal ,或者还有一些其他类似的朋友&#34;喜欢涉及的关系。
我的问题是,在这种情况下我能做些什么来从SensorBase继承而不会出现此错误?如果没有,是否还有另一个涉及依赖注入(IOC)的解决方案,这有助于实现我在手机没有指南针时实例化虚拟课程的目标?
以下是我收到错误的CompassDummy类的代码:
public sealed class CompassDummy : SensorBase<CompassReading>
{
public CompassDummy()
{
}
} // public class CompassDummy
答案 0 :(得分:4)
我的猜测是Compass类可以继承SensorBase而我的虚拟类不能继承,因为它与SensorBase位于同一个程序集中。也许SensorBase的构造函数标记为内部
正确。您不应该自己派生SensorBase<T>
:它只是Accelerometer
,Compass
,Gyroscope
和{{1}的基类}。
您是否打算在自己的代码中使用这个虚拟Motion
类,而不是将它传递到任何地方?如果是这样,请在此处使用组合而不是继承:
Sensor
然后,在您的代码中,使用您的public interface ICompass
{
void Start();
// Whatever other methods you need
}
public class RealCompass : ICompass
{
private readonly Compass compass;
public RealCompass(Compass compass)
{
this.compass = compass;
}
public void Start()
{
this.compass.Start();
}
}
public class StubCompass : ICompass
{
public void Start()
{
// Do nothing...
}
}
界面。
答案 1 :(得分:1)
使用接口允许用canton7替换混凝土罗盘类型as suggested,这是解决这个问题的一个很好的解决方案。根据您的需要,另一个需要考虑的解决方案是proxy pattern。
基本上,您可以创建一个在整个代码中使用的CompassProxy
课程。这个类与框架Compass
类具有相似或相同的方法/属性,并且它的每个实例都包含Compass
或CompassDummy
的相应实例,具体取决于手机&#39 ; s硬件。
对代理类的调用将被转发到包含的&#34;后端&#34;罗盘类,它可以完成真正的工作,然后任何结果都会传回给调用者。
就像一个例子,这里是CompassProxy类的一些原型代码:
class CompassProxy {
private readonly Compass _realCompass = null;
private readonly CompassDummy _dummyCompass = null;
private readonly bool _hasCompass = false;
public CompassProxy() {
// the creation logic could be moved out of this class, if need be
if ( HasRealCompassHardware() ) {
_realCompass = Compass.GetDefault(); // ...or whatever is the proper way to obtain an instance
_hasCompass = true;
} else {
_dummyCompass = new CompassDummy();
}
}
public CompassReading GetCurrentReading() {
return _hasCompass ? _realCompass.GetCurrentReading() : _dummyCompass.GetCurrentReading();
}
}