没有使用泛型的显式叶节点类的父子数据结构
我有以下示例关系:
namespace Yesod
{
public class Program
{
//
//
//
public struct Particle
{
public byte type;
}
//
//
//
public class Entity<T>
{
public Entity<Entity<T>> Parent
{ get; private set; }
//
//
//
public Entity(Entity<Entity<T>> parent)
{
this.Parent = parent;
}
}
//
//
//
public sealed class Atom : Entity<Particle>
{
public Atom(Entity<Atom> parent)
: base(parent) // Compile Error.
{ }
}
//
//
//
public sealed class Molecule : Entity<Atom>
{
public Molecule()
: base(null)
{ }
}
static void Main(string[] args)
{
}
}
}
如何解决上面产生的以下编译错误?
Argument 1: cannot convert from 'Yesod.Program.Entity<Yesod.Program.Atom>' to 'Yesod.Program.Entity<Yesod.Program.Entity<Yesod.Program.Particle>>'
评论回复#1: 具体来说,代码尝试将 Atom 类型的对象分配
Entity<Atom>
类型的对象
Entity<Entity<Particle>>
给Atom
public sealed class Atom : Entity<Particle>
,预计
Entity<Atom>
会分解为
Entity<Entity<Particle>>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不懂 C#,但 Java 程序员偶尔也会遇到这个问题。
环顾其他 C# 源代码,我认为您可以做您想做的事情(在类型安全方面有一点损失):
Java 答案将涉及
?扩展实体
。基本问题是,尽管Molecule
是一个Entity
,但编译器无法知道Molecule
也是一个>实体<实体<粒子>
。毕竟,假设Entity
维护了一个子级列表,并且具有合理的addChild(T child)
方法。然后编译器会希望确保您只添加原子作为分子的子代。但是,如果Molecule
是Entity>
,那么没有什么可以阻止您这样做:此模式的正确完全类型安全解决方案涉及 self 类型,Java 和 C# 没有。 Java 模式
Foo>
(及其 C# 等效项)很接近,但工作起来很滑。除此之外,声明时间差异将使这种模式更加清晰。I don't know C#, but Java programmers occasionally slam into this issue too.
Looking around at other C# sources, I think you can do what you want (with a little loss in type safety) with:
The Java answer would involve
? extends Entity<T>
. The basic issue is that althoughMolecule
is anEntity<Atom>
, there's no way for the compiler to know thatMolecule
is also anEntity<Entity<Particle>>
. After all, suppose thatEntity
maintained a list of children, and had the sensibleaddChild(T child)
method on it. Then the compiler would want to ensure that you only addedAtom
s as children of molecules. But ifMolecule
is anEntity<Entity<Particle>>
, then nothing would prevent you from doing:The proper fully type-safe solution for this pattern involves self types, which Java and C# don't have. The Java pattern of
Foo<F extends Foo<F>>
(and its C# equivalent) comes close, but is very slippery to work with. Barring that, declare-time variance would make this pattern cleaner.尽管 Daniel Martin 发布的潜在解决方案永远不会起作用(诚然警告过),但对为什么我的代码也永远不会起作用的解释是 100% 准确的,它让我发现 C# 4.0 使用其新功能解决了这个原本预期的功能。 通用协方差&逆变 语言特征。
以下是解决方案,供审查:
谢谢丹尼尔·马丁。由于我目前的代表,我无法对你进行 1 比。分数。对于那些想知道的人来说,上面是一个愚蠢的模型,旨在突出明显的亲子关系,以帮助人们理解这个问题。现实世界的预期用途将是一个高级版本,将用于计算机图形学领域,以明确定义的递归方式解决相干空间划分问题。
Although the potential solution posted by Daniel Martin would never work (as admittedly warned), the explanation on why my code would too never work is 100% accurate, and it has led me to discover that C# 4.0 solves this otherwise expected functionality using its new generic covariance & contra-variance language features.
Below is the solution, for review:
Thanks Daniel Martin. I could not 1-up you due to my current rep. score. To those wondering, the above is a silly mock up aimed to highlight obvious parent-child relationships to help those understand the question. The real-world intended use will be an advanced version that will be employed in the field of computer graphics to solve the Coherent Space Partitioning problem in a well-defined and recursive manner.