Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# c中的循环泛型类型#_C#_Generics - Fatal编程技术网

C# c中的循环泛型类型#

C# c中的循环泛型类型#,c#,generics,C#,Generics,我需要做一个图,我希望边和顶点是泛型的 public interface IVertex<TVertex, TEdge> where TVertex : IVertex<?> where TEdge : IEdge<?> { bool AddEdge(TEdge e); TEdge FindEdge(TVertex v); } public interface IEdge<TVertex> wher

我需要做一个图,我希望边和顶点是泛型的

public interface IVertex<TVertex, TEdge>
        where TVertex : IVertex<?>
        where TEdge : IEdge<?>
{
    bool AddEdge(TEdge e);
    TEdge FindEdge(TVertex v);
}

public interface IEdge<TVertex> where TVertex : IVertex<?>
{
    TVertex From { get; }
}
公共接口IVertex
TVertex所在地:IVertex
特奇:伊奇在哪里
{
布尔加德奇(TEdge);
TEdge FindEdge(TVertex v);
}
公共接口IEdge,其中TVertex:IVertex
{
来自{get;}的TVertex
}
但是,边需要顶点类型,顶点需要边类型
我该怎么办?

我想你把事情弄得比实际情况更复杂了。
你喜欢这个工作吗

public interface IVertex<T>
{
    bool AddEdge(IEdge<T> e);
    IEdge<T> FindEdge(IVertex<T> v);
}

public interface IEdge<T>
{
    IVertex<T> From { get; }
}
公共接口IVertex
{
bool-AddEdge(IEdge-e);
IEdge FindEdge(IVertex v);
}
公共接口边缘
{
来自{get;}的IVertex
}

似乎您希望边和顶点存储一些值。如果希望顶点具有
TV
值,而边具有
TE
值,则可以执行以下操作:

public interface IVertex<TV, TE>
{
    TV Value { get; }
    bool AddEdge(IEdge<TV, TE> e);
    IEdge<TV, TE> FindEdge(IVertex<TV, TE> v);
}

public interface IEdge<TV, TE> 
{
    TE Value { get; }
    IVertex<TV, TE> From { get; }
}
公共接口IVertex
{
电视值{get;}
bool-AddEdge(IEdge-e);
IEdge FindEdge(IVertex v);
}
公共接口边缘
{
TE值{get;}
来自{get;}的IVertex
}

问题在于您已经使用类型约束创建了一个递归定义。你是说
IVertex
其中
A
必须是
IVertex
,其中
B
必须是
IVertex
,等等。。。在某些时候,您必须指定一个类型或接口作为泛型参数。已经提出了一些好的解决方案。这里是另一个情况下,你需要更多的选择

您可以引入另一种类型或接口(非泛型)来打破递归定义

public interface IVertex<TVertex, TEdge>
        where TVertex : IVertex
        where TEdge : IEdge
{
    bool AddEdge(TEdge e);
    TEdge FindEdge(TVertex v);
}

public interface IEdge<TVertex> where TVertex : IVertex
{
    TVertex From { get; }
}
公共接口IVertex
TVertex所在地:IVertex
特奇:伊奇在哪里
{
布尔加德奇(TEdge);
TEdge FindEdge(TVertex v);
}
公共接口IEdge,其中TVertex:IVertex
{
来自{get;}的TVertex
}

虽然这是否是一个好主意还存在争议,但编译器对这种“循环”定义并不介意:

interface IVertex<TVertex, TEdge> where TVertex : IVertex<TVertex,TEdge>
                                  where TEdge : IEdge<TVertex,TEdge>
{

}

interface IEdge<TVertex, TEdge> where TVertex : IVertex<TVertex, TEdge>
                                where TEdge : IEdge<TVertex, TEdge>
{

}
接口IVertex,其中TVertex:IVertex
特奇:伊奇在哪里
{
}
接口边缘,其中TVertex:IVertex
特奇:伊奇在哪里
{
}
然后你可以写,例如:

class FooVertex : IVertex<FooVertex,BarEdge>
{

}

class BarEdge : IEdge<FooVertex,BarEdge>
{

}
类FootVertex:IVertex
{
}
巴里奇班:伊里奇
{
}

TEDGEFINDEDGE(TVertex v)
这个方法做什么?我真希望有人能解决这个问题,因为到目前为止,我所遇到的唯一的解决方案就是在通用
IVertex
上创建一个非通用的
IVertex
,或者在
IVertex
上添加
TItem
。我认为这个问题需要解释一下你为什么想要这个方法泛型类型参数。举一个例子,删除所有
TVertex
s和
TEdge
s并用
IVertex
IEdge
(关于方法/属性签名)替换它们是不够的,因此我们理解您试图实现的目标Ts代表什么?@BenAaronson@stuartd Er,对,但在这种情况下,这些类型参数具体表示什么?在这个问题中,有两种类型,
TVertex
TEdge
,它们分别被限制实现
IVertex
IEdge
。在这种情况下,
T
似乎是一个完全不受约束的type@BenAaronson我猜这是顶点可以保存的数据类型。但是我看到这个解决方案可能不是OP想要的。@BenAaronson
T
s代表
问题中的泛型类型