I have a set of data structures that looks like follows:
IDataPoint
interface (to secure the existence of a value and a coordinate point)ITuple
(to secure the existence of at least one (X) coordinate) My problem is, that I haven't found out how to make the Coord
property of the IDataPoint
generic so that coordinates can be either 2d or 3d (or sth else if needed later on). This is my attempt:
public interface IDataPoint
{
float Value { get; }
<Tuple> Coords { get; } where <ITuple> : ITuple
string ToString();
}
Where is my error or is this simply not possible?
Rest of the code
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;
}
}
Interface
public interface IDataPoint<TTuple>
{
float Value { get; }
TTuple Coords { get; }
string ToString();
}
Usage
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;
}
}
Do it like you did it in your ITuple
interface by providing the generics and its constraints in the interface declaration:
public interface IDataPoint<T,T2> where T : ITuple<T2>
{
float Value { get; }
T Coords { get; }
string ToString();
}
Your Coords
property now has the type T
, and T
has to implement the interface ITuple<T2>
. Your class BarDataPoint
should be defined like this:
public struct BarDataPoint : IDataPoint<TwoTuple<float>,float>
You'll have to tell the compiler the generic type of ITuple<T>
twice. Online demo: https://dotnetfiddle.net/CYw1bR
What you can do is this:
public interface IDataPoint
{
float Value { get; }
ITuple Coords { get; }
string ToString();
}
you dont need generics. ITuple
is general purpose base implementation for tuples. these are all derived from 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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.