递归约束:DBase< T> :其中T:DBase< T>意思? [英] Recursive constraints: What does DBase<T> : where T : DBase<T> mean?
问题描述
我以为我理解通用的约束,直到遇到这个约束。
公共类DBase< T> :DbContext,IDisposable,其中T:DBase< T>。
如何成为 DBase< T>
?
如果可以的话,这意味着什么?
此代码可以编译并正常运行。我没有解决问题。我只是不明白。
在这里使用
公共类ChildDb:DBase< ChildDb>
同样,这对我来说并不算。
T
是DBase< T>
?
没有限制,可以防止从其自身派生通用参数。虽然您所提供的示例无法直接理解。
在几何图形中,顶点(复数:顶点或顶点)是两个或更多曲线,直线或边相交的点。作为此定义的结果,两条线相交形成角度的点以及多边形和多面体的角为顶点。 1
如何描述一个顶点(一个点)?
//非常简单的示例
公共类的顶点
{
public int X {get;组; }
public int Y {get;组; }
}
现在我们如何为该类添加相关的Verticies集合,但仅
公共类Vertex< TVertex> :Vertex
其中TVertex:Vertex< TVertex>
{
public IEnumerable< TVertex>顶点{get;组; }
}
它是通用的说法:
public Vertex2
{
public IENumerable< Vertex2>顶点{get;组; }
}
但是,当我从Vertex2导出时,我的 Vertices
始终必须为 IEnumerable< Vertex2>
,允许Vertices成为派生类的正确方法是使用这种类型的self-
对不起Erik,我在细节上失去了重点。递归给我带来了什么?
使用 Vertex2
,我们的派生类型将失去访问权限到其他派生属性:
公共类MyVertex2:Vertex2
{
public int Id {get;组; }
}
所以
var a = new MyVertex2 {Id = 1};
var b = new MyVertex2 {Id = 2};
a.Vertices = new List< Vertex2> {b};
b.Vertices = new List< Vertex2> { 一种 };
//无法访问ID,因为它是Vertex2而不是MyVertex2
var bId = a.Vertices.First()。Id;
可以将其投射,但随后将其投射到任何地方(不是 DRY )...如果它不是MyVertex(MullReferencesException或InvalidCastException)怎么办。
公共类MyVertex:Vertex< MyVertex>
{
public ind Id {get;组; }
}
var a = new MyVertex {Id = 1};
var b = new MyVertex {Id = 2};
a.Vertices = new List< MyVertex> {b};
b.Vertices = new List< MyVertex> { 一种 };
var bId = a.Vertices.First()。Id;
//甚至
var aId = a.Vertices.First()。Vertices.First();
每次导航到顶点时,我们都会得到正确派生类型,不是基类。
I thought I understood generic constraints until I ran across this.
public class DBase<T> : DbContext, IDisposable where T : DBase<T>
How can T be DBase<T>
?
And if it can, what does it mean?
This code compiles and runs fine. I'm not fixing a problem. I just don't understand it.
It is used here
public class ChildDb : DBase<ChildDb>
Which, again, doesn't compute for me. It passes itself as a type parameter?
How can
T
beDBase<T>
?
There is no limitation that prevents a Generic Parameter from deriving from itself. While it's not directly understandable with the example you've given. What about a Vertex / Vertice?
Excerpt from Wikipedia:
In geometry, a vertex (plural: vertices or vertexes) is a point where two or more curves, lines, or edges meet. As a consequence of this definition, the point where two lines meet to form an angle and the corners of polygons and polyhedra are vertices.1
How does one describe a Vertex (a point)?
// very simplified example
public class Vertex
{
public int X { get; set; }
public int Y { get; set; }
}
Now how do we add a collection of relationed Verticies to this class but only allow things that derive from this class?
public class Vertex<TVertex> : Vertex
where TVertex : Vertex<TVertex>
{
public IEnumerable<TVertex> Vertices { get; set; }
}
It a generic version of say:
public Vertex2
{
public IENumerable<Vertex2> Vertices { get; set; }
}
However when I derive from Vertex2, my Vertices
will always have to be IEnumerable<Vertex2>
, and the correct way to allow Vertices to be a derived class is to use this type of self-reference generic.
I'm sorry Erik, I lost the point in the details. What have I gained by the recursion?
Using Vertex2
, our derived types lose access to other derived properties:
public class MyVertex2: Vertex2
{
public int Id { get; set; }
}
so
var a = new MyVertex2 {Id = 1 };
var b = new MyVertex2 { Id = 2 };
a.Vertices = new List<Vertex2> { b };
b.Vertices = new List<Vertex2> { a };
// can't access Id because it's a Vertex2 not a MyVertex2
var bId = a.Vertices.First().Id;
Sure you could cast it, but then you're casting it everywhere (that's not DRY)... and what if it's not a MyVertex (MullReferencesException or InvalidCastException).
public class MyVertex: Vertex<MyVertex>
{
public int Id { get; set; }
}
var a = new MyVertex {Id = 1 };
var b = new MyVertex { Id = 2 };
a.Vertices = new List<MyVertex > { b };
b.Vertices = new List<MyVertex > { a };
var bId = a.Vertices.First().Id;
// or even
var aId = a.Vertices.First().Vertices.First();
each time we navigate to a vertices we get the correct derived type, not the base class.
这篇关于递归约束:DBase< T> :其中T:DBase< T>意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!