C#:共享结构域和继承



现在我知道C#不支持结构继承有很多原因。然而,我想知道是否仍然可以为数据类型实现某种形式的层次结构,这样函数就可以依赖于类型B或类型C的变量,因为它们都继承自类型a。

更具体地说:我有两个结构,它们有一个值字段和坐标(2D和3D(

public struct BarDataPoint
{
public TwoTuple<float> coords { get; }
public float value { get; }
public BarDataPoint(TwoTuple<float> coords, float value)
{
this.coords = coords;
this.value = value;
}
}
public struct ScatterDataPoint
{
public ThreeTuple<float> coords { get; }
public float value { get; }
public ScatterDataPoint(ThreeTuple<float> coords, float value)
{
this.coords = coords;
this.value = value;
}
}

我还有这个函数,它应该可以找到数据点阵列的最大值

{
// Finds the maximum value of an BarData array
float maxValue = data[0].value;
foreach (BarDataPoint dataPoint in data)
{
maxValue = (maxValue < dataPoint.value) ? dataPoint.value : maxValue;
}
return maxValue;
}

我想推广这个函数,这样它就可以接受这两种类型(或任何其他带有"值"字段的类型(并返回其最大值。

这可能吗?如果是,如何?或者你会推荐一个完全不同的设计吗?

结构实现接口没有问题:

public interface IDataPoint
{
float Value { get; }
}
public struct BarDataPoint : IDataPoint
public struct ScatterDataPoint : IDataPoint

然后你可以这样做:

{
float maxValue = data[0].Value;
foreach (IDataPoint dataPoint in data)
{
maxValue = (maxValue < dataPoint.Value) ? dataPoint.Value : maxValue;
}
return maxValue;
}

为了避免上例中装箱导致的性能打击,您可以使实现方法通用:

float GetMaxValue<TDataPoint>(TDataPoint[] data) where TDataPoint : IDataPoint
{
float maxValue = data[0].Value;
foreach (TDataPoint dataPoint in data)
{
maxValue = (maxValue < dataPoint.Value) ? dataPoint.Value : maxValue;
}
return maxValue;
}

只要确保在泛型方法中始终将数据引用为TDataPoint,因为使用IDataPoint会导致装箱(因为接口是引用类型(。

这之所以有效,是因为通用方法将被解析为float GetMaxValue(BarDataPoint[] data)float GetMaxValue(ScatterDataPoint[] data),而不是float GetMaxValue(IDataPoint[] data)


顺便说一句,如果你只需要知道最大值,Enumerable.Max应该完全按照你的要求进行,而不需要上述方法:

BarDataPoint[] data = //...
float max = data.Max(x => x.Value);

最新更新