接口的 属性 的通用类型

Generic type for property of an Interface

我有一组数据结构,如下所示:

我的问题是,我还没有找到如何使 IDataPoint 泛型的 Coord 属性 的坐标可以是 2d 或 3d(或某物)否则,如果以后需要的话)。这是我的尝试:

public interface IDataPoint
{ 
    float Value { get; }
    <Tuple> Coords { get; } where <ITuple> : ITuple

    string ToString();
}

我的错误在哪里,或者这根本不可能吗?

其余代码

public interface ITuple<T>
{
    T X { get; }

    string ToString();
}

public struct TwoTuple<T> : ITuple<T>
{
    public T X { get; }
    public T Y { get; }
    public TwoTuple(T x, T y)
    {
        X = x;
        Y = y;
    }

    public override string ToString()
    {
        return "(" + X + ", " + Y + ")";
    }
}

public struct ThreeTuple<T> : ITuple<T>
{
    public T X { get; }
    public T Y { get; }
    public T Z { get; }
    public ThreeTuple(T x, T y, T z)
    {
        X = x;
        Y = y;
        Z = z;
    }

    public override string ToString()
    {
        return "(" + X + ", " + Y + ", " + Z + ")";
    }
}

public interface IDataPoint
{ 
    float Value { get; }
    <Tuple> Coords { get; } where <ITuple> : ITuple

    string ToString();
}

public struct BarDataPoint : IDataPoint
{
    public TwoTuple<float> Coords { get; }
    public float Value { get; }
    public BarDataPoint(TwoTuple<float> Coords, float Value)
    {
        this.Coords = Coords;
        this.Value = Value;
    }

    public override string ToString()
    {
        return "Coordinates: " + Coords + "; Value: " + Value;
    }
}

public struct ScatterDataPoint : IDataPoint
{
    public ThreeTuple<float> Coords { get; }
    public float Value { get; }
    public ScatterDataPoint(ThreeTuple<float> coords, float value)
    {
        this.Coords = coords;
        this.Value = value;
    }

    public override string ToString()
    {
        return "Coordinates: " + Coords + "; Value: " + Value;
    }
}

通过在接口声明中提供泛型及其约束,就像在 ITuple 接口中那样做:

public interface IDataPoint<T,T2> where T : ITuple<T2>
{ 
    float Value { get; }
    T Coords { get; } 

    string ToString();
}

您的 Coords 属性 现在具有类型 T,并且 T 必须实现接口 ITuple<T2>。你的 class BarDataPoint 应该这样定义:

public struct BarDataPoint : IDataPoint<TwoTuple<float>,float>

您必须将 ITuple<T> 的泛型类型告诉编译器两次。在线演示:https://dotnetfiddle.net/CYw1bR

你能做的是:

public interface IDataPoint 
{
    float Value { get; }
    ITuple Coords { get; }

    string ToString();
}

你不需要泛型。 ITuple 是元组的通用基础实现。 这些都来自 ITuple

System.Tuple<T1>
System.Tuple<T1,T2>
System.Tuple<T1,T2,T3>
System.Tuple<T1,T2,T3,T4>
System.Tuple<T1,T2,T3,T4,T5>
System.Tuple<T1,T2,T3,T4,T5,T6>
System.Tuple<T1,T2,T3,T4,T5,T6,T7>
System.Tuple<T1,T2,T3,T4,T5,T6,T7,TRest>
System.ValueTuple
System.ValueTuple<T1>
System.ValueTuple<T1,T2>
System.ValueTuple<T1,T2,T3>
System.ValueTuple<T1,T2,T3,T4>
System.ValueTuple<T1,T2,T3,T4,T5>
System.ValueTuple<T1,T2,T3,T4,T5,T6>
System.ValueTuple<T1,T2,T3,T4,T5,T6,T7>
System.ValueTuple<T1,T2,T3,T4,T5,T6,T7,TRest>

ITuple Documentation

界面

public interface IDataPoint<TTuple>
{
    float Value { get; }
    TTuple Coords { get; }

    string ToString();
}

用法

 public struct BarDataPoint : IDataPoint<ThreeTuple<float>>
{
    public float Value { get; }

    public ThreeTuple<float> Coords { get; set; }

    public BarDataPoint(ThreeTuple<float> Coords, float Value)
    {
        this.Coords = Coords;
        this.Value = Value;
    }

    public override string ToString()
    {
        return "Coordinates: " + Coords + "; Value: " + Value;
    }
}