简体   繁体   English

接口属性的通用类型

[英]Generic type for property of an Interface

I have a set of data structures that looks like follows:我有一组如下所示的数据结构:

  • different DataPoints that implement the IDataPoint interface (to secure the existence of a value and a coordinate point)实现IDataPoint接口的不同数据点(以确保值和坐标点的存在)
  • each DataPoint might have different coordinate types (2D, 3D etc)每个数据点可能有不同的坐标类型(2D、3D 等)
  • the coordinates are stored in generic tuples that all implement the interface ITuple (to secure the existence of at least one (X) coordinate)坐标存储在通用元组中,这些元组都实现了接口ITuple (以确保至少存在一个 (X) 坐标)

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).我的问题是,我还没有找到如何使IDataPointCoord属性通用,以便坐标可以是 2d 或 3d(或者以后需要的话)。 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:通过在接口声明中提供泛型及其约束,像在ITuple接口中那样做:

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> .您的Coords属性现在具有类型T ,并且T必须实现接口ITuple<T2> Your class BarDataPoint should be defined like this:你的类BarDataPoint应该像这样定义:

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

You'll have to tell the compiler the generic type of ITuple<T> twice.您必须将ITuple<T>的泛型类型告诉编译器两次。 Online demo: https://dotnetfiddle.net/CYw1bR在线演示: 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. ITuple是元组的通用基础实现。 these are all derived from 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 ITuple 文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM