My apologies if it is quite confusing.
I have this two main interfaces. First the ISensor interface:
public interface ISensor<TReading>
where TReading : ISensorReading<ISensor<TReading>>
{
event SensorReadingCompletedEH<ISensor<TReading>, TReading> ReadCompleted;
TReading Read();
}
And the second interface: ISensorReading:
public interface ISensorReading<TSensor>
where TSensor : ISensor<ISensorReading<TSensor>>
{
TSensor Sensor { get; }
}
It leads to the following errors:
The type ISensor<TReading> must be convertible to
ISensor<ISensorReading<ISensor<TReading>>> in order to use it as parameter TSensor in the generic type or method ISensorReading<TSensor>
and
The type ISensorReading<TSensor> must be convertible to
ISensorReading<ISensor<ISensorReading<TSensor>>> in order to use it as parameter TReading in the generic type or method ISensor<TReading>
I fear it is due to an insolvable circular reference at compile time; however I want to ensure congruence for derived types like TelemetricSensor : ISensor<TelemetricReading> and
TelemetricReading : ISensorReading<TelemetricSensor>
Which other aproaches should I use to allow simple casting and type safe?
I am using .NET 2.0 and VS2005
Thanks all for your answers.
Finally this is the solution I choose for the problem. Hope to be usefull. If you have comments or know a way to impriove it without change the framework, let me know.
First I created an ISensor interface with the minimal requirements. After that I defined a new ISensor generic interface as follows:
With theese interfaces defined and following the same structures, I was able to made the first implementation: A TelemetricSensor class with its correspondient ITelemetricReading
Here TReading of the TelemetricSensor abstract class is interesting. It is defined as
which may appear to be redundant because ITelemetricReading inherits from ISensorReading, but it is required to get the code compile and met the requirement for both
property and
method. Finally to skip tedious casting (and perhaps some errors) mutiple overloads of Read(…) can be done so each provides the data casted correctly and also met all interface implementations.