递归约束:DBase< T> :其中T:DBase< T>意思? [英] Recursive constraints: What does DBase<T> : where T : DBase<T> mean?

查看:81
本文介绍了递归约束:DBase< T> :其中T:DBase< T>意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我理解通用的约束,直到遇到这个约束。

 公共类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 be DBase<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&lt; T&gt; :其中T:DBase&lt; T&gt;意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆