接口的 属性 的通用类型
Generic type for property of an Interface
我有一组数据结构,如下所示:
- 实现
IDataPoint
接口的不同数据点(以确保值和坐标点的存在)
- 每个数据点可能有不同的坐标类型(2D、3D 等)
- 坐标存储在通用元组中,这些元组都实现了接口
ITuple
(以确保至少存在一个 (X) 坐标)
我的问题是,我还没有找到如何使 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>
界面
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;
}
}
我有一组数据结构,如下所示:
- 实现
IDataPoint
接口的不同数据点(以确保值和坐标点的存在) - 每个数据点可能有不同的坐标类型(2D、3D 等)
- 坐标存储在通用元组中,这些元组都实现了接口
ITuple
(以确保至少存在一个 (X) 坐标)
我的问题是,我还没有找到如何使 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>
界面
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;
}
}