循环 c# 中的泛型类型

本文关键字:泛型类型 循环 | 更新日期: 2023-09-27 18:35:48

我需要制作图形,我希望边和顶点是通用类型

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; }
}
但是,边需要顶

点类型,顶点需要边类型我该怎么办?

循环 c# 中的泛型类型

我认为你让它比它需要的更复杂。
这样的事情会起作用吗?

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

虽然它是否真的是一个好主意是有争议的,但编译器并不介意这种"循环"定义:

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>
{
}

然后你可以写,例如:

class FooVertex : IVertex<FooVertex,BarEdge>
{
}
class BarEdge : IEdge<FooVertex,BarEdge>
{
}

似乎你想要边和顶点存储一些值。如果您希望顶点具有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<A> A必须IVertex<B>的地方,B必须IVertex<C>的地方,等等......在某些时候,您必须指定实际指定类型或接口作为泛型参数。已经提出了几个很好的解决方案。这是另一个,以防您需要更多选项...

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

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; }
}