【发布时间】:2015-05-21 19:09:50
【问题描述】:
如何重组我的代码以消除在指示点发生的运行时错误?
DataSeries<SimpleDataPoint> 需要能够以某种方式转换回 IDataSeries<IDataPoint>
我尝试过使用两个接口的继承,如下所示:
public class DataSeries<TDataPoint> : IDataSeries<TDataPoint>, IDataSeries<IDataPoint> 但收到编译器错误:
'DataSeries<TDataPoint>'不能同时实现
'IDataSeries<TDataPoint>'和
'IDataSeries<IDataPoint>'因为它们可能会针对某些类型参数替换统一
使用协变似乎不是一种选择,因为我无法使接口协变或逆变。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1 {
class Program {
[STAThread]
static void Main(string[] args) {
var source = new object();
// compiles fine, but ...
// runtime error here - cannot cast
var ds = (IDataSeries<IDataPoint>)new DataSeries<SimpleDataPoint>(source);
Console.ReadKey();
}
}
public interface IDataPoint {
int Index { get; set; }
double Value { get; set; }
DateTime TimeStampLocal { get; set; }
IDataPoint Clone();
}
public sealed class SimpleDataPoint : IDataPoint {
public int Index { get; set; }
public double Value { get; set; }
public DateTime TimeStampLocal { get; set; }
public IDataPoint Clone() {
return new SimpleDataPoint {
Index = Index,
Value = Value,
TimeStampLocal = TimeStampLocal,
};
}
}
public interface IDataSeries<TDataPoint> where TDataPoint : class, IDataPoint {
object Source { get; }
int Count { get; }
double GetValue(int index);
DateTime GetTimeStampLocal(int index);
TDataPoint GetDataPoint(int index);
TDataPoint GetLastDataPoint();
void Add(TDataPoint dataPoint);
IDataSeries<TDataPoint> Branch(object source);
}
public class DataSeries<TDataPoint> : IDataSeries<TDataPoint> where TDataPoint : class, IDataPoint {
readonly List<TDataPoint> _data = new List<TDataPoint>();
public object Source {
get;
private set;
}
public DataSeries(object source) {
Source = source;
}
public int Count {
get { return _data.Count; }
}
public TDataPoint GetDataPoint(int index) {
return _data[index];
}
public TDataPoint GetLastDataPoint() {
return _data[_data.Count - 1];
}
public DateTime GetTimeStampLocal(int index) {
return _data[index].TimeStampLocal;
}
public double GetValue(int index) {
return _data[index].Value;
}
public void Add(TDataPoint dataPoint) {
_data.Add(dataPoint);
}
public IDataSeries<TDataPoint> Branch(object source) {
throw new NotImplementedException();
}
}
}
【问题讨论】:
-
您发布的是编译时错误,而不是强制转换异常。
-
@Yuval,代码编译。我正在寻找运行时转换错误的解决方案。提到的编译错误是一个错误,阻止了我尝试过的一种可能的解决方案。
-
实际上,我认为存在代码异味,我不仅要修复运行时错误,还要构建没有异味的代码 :)
-
@YuvalItzchakov,感谢您的编辑
-
您可以创建两个额外的接口。一个协变:
IReadOnlyDataSeries<out TDataPoint>,另一个在 TDataPoint 上逆变:IWriteOnlyDataSeries<in TDataPoint>
标签: c# generics casting covariance