C# 没有使用泛型的显式叶节点类的父子数据结构
我有以下示例关系:C# 没有使用泛型的显式叶节点类的父子数据结构,c#,c#-4.0,covariance,generics,C#,C# 4.0,Covariance,Generics,我有以下示例关系: namespace Yesod { public class Program { // // // public struct Particle { public byte type; } // // // public class Entity<T>
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)
{
}
}
}
namespace-Yesod
{
公共课程
{
//
//
//
公共结构粒子
{
公共字节类型;
}
//
//
//
公共类实体
{
公共实体母公司
{get;私有集;}
//
//
//
公共实体(实体父实体)
{
这个。父=父;
}
}
//
//
//
公共密封类Atom:实体
{
公共原子(实体父级)
:base(parent)//编译错误。
{ }
}
//
//
//
公共密封类分子:实体
{
公共分子()
:base(空)
{ }
}
静态void Main(字符串[]参数)
{
}
}
}
如何解决上面产生的以下编译错误
Argument 1: cannot convert from 'Yesod.Program.Entity<Yesod.Program.Atom>' to 'Yesod.Program.Entity<Yesod.Program.Entity<Yesod.Program.Particle>>'
参数1:无法从'Yesod.Program.Entity'转换为'Yesod.Program.Entity'
评论回复#1:
具体来说,代码试图分配类型为的对象
Entity<Atom>
Entity<Entity<Particle>>
实体
类型的对象
Entity<Atom>
Entity<Entity<Particle>>
实体
as-Atom实现为
public sealed class Atom : Entity<Particle>
公共密封类原子:实体
据此
Entity<Atom>
实体
预计将细分为
Entity<Entity<Particle>>
实体
我不懂C,但Java程序员偶尔也会猛烈抨击这个问题
环顾其他C#来源,我认为您可以通过以下方式做您想要做的事情(在类型安全方面稍有损失):
这种模式的正确的完全类型安全解决方案包括自类型,而Java和C#没有自类型。Foo
()的Java模式非常接近,但使用起来非常不方便。除此之外,声明时间差异将使此模式更清晰。我不知道C#,但Java程序员偶尔也会遇到这个问题
环顾其他C#来源,我认为您可以通过以下方式做您想要做的事情(在类型安全方面稍有损失):
这种模式的正确的完全类型安全解决方案包括自类型,而Java和C#没有自类型。
Foo
()的Java模式非常接近,但使用起来非常不方便。除此之外,声明时间差异将使此模式更清晰。尽管Daniel Martin发布的潜在解决方案永远不会起作用(诚然,正如所警告的那样),但关于我的代码为什么永远不会起作用的解释是100%准确的,这让我发现,C#4.0使用其新的语言特性解决了这一预期功能
以下是供审查的解决方案:
namespace Yesod
{
public class Program
{
//
//
//
public struct Particle
{
public byte type;
}
// Fix with C# 4.0 using out keyword.
//
//
public interface IEntity<out T>
{
IEntity<IEntity<T>> Parent
{ get; }
}
//
//
//
public class Entity<T> : IEntity<T>
{
public IEntity<IEntity<T>> Parent
{ get; private set; }
//
//
//
public Entity(IEntity<IEntity<T>> parent)
{
this.Parent = parent;
}
}
//
//
//
public sealed class Atom : Entity<Particle>
{
public Atom(Entity<Atom> parent)
: base(parent) // No more compile error.
{ }
}
//
//
//
public sealed class Molecule : Entity<Atom>
{
public Molecule()
: base(null)
{ }
}
//
//
//
static void Main(string[] args)
{
// Now this can be done.
Molecule water = new Molecule();
Atom H1 = new Atom(water);
Atom O1 = new Atom(water);
Atom O2 = new Atom(water);
}
}
}
namespace-Yesod
{
公共课程
{
//
//
//
公共结构粒子
{
公共字节类型;
}
//用C#4.0使用out关键字进行修复。
//
//
公共界面的开放性
{
亲本
{get;}
}
//
//
//
公共类实体:通用性
{
公母
{get;私有集;}
//
//
//
公共实体(企业母公司)
{
这个。父=父;
}
}
//
//
//
公共密封类Atom:实体
{
公共原子(实体父级)
:base(parent)//不再有编译错误。
{ }
}
//
//
//
公共密封类分子:实体
{
公共分子()
:base(空)
{ }
}
//
//
//
静态void Main(字符串[]参数)
{
//现在可以这样做了。
水分子=新分子();
原子H1=新原子(水);
原子O1=新原子(水);
原子O2=新原子(水);
}
}
}
谢谢丹尼尔·马丁。由于我目前的代表分数,我无法1-up你。对于那些想知道的人来说,上面是一个愚蠢的模型,旨在强调明显的亲子关系,帮助那些理解这个问题的人。真实世界的预期用途将是一个高级版本,将用于计算机图形学领域,以明确定义和递归的方式解决连贯的空间划分问题。尽管丹尼尔·马丁发布的潜在解决方案永远不会起作用(正如公认的警告),关于为什么我的代码永远无法工作的解释是100%准确的,它让我发现C#4.0使用其新的语言特性解决了这一预期功能 以下是供审查的解决方案:
namespace Yesod
{
public class Program
{
//
//
//
public struct Particle
{
public byte type;
}
// Fix with C# 4.0 using out keyword.
//
//
public interface IEntity<out T>
{
IEntity<IEntity<T>> Parent
{ get; }
}
//
//
//
public class Entity<T> : IEntity<T>
{
public IEntity<IEntity<T>> Parent
{ get; private set; }
//
//
//
public Entity(IEntity<IEntity<T>> parent)
{
this.Parent = parent;
}
}
//
//
//
public sealed class Atom : Entity<Particle>
{
public Atom(Entity<Atom> parent)
: base(parent) // No more compile error.
{ }
}
//
//
//
public sealed class Molecule : Entity<Atom>
{
public Molecule()
: base(null)
{ }
}
//
//
//
static void Main(string[] args)
{
// Now this can be done.
Molecule water = new Molecule();
Atom H1 = new Atom(water);
Atom O1 = new Atom(water);
Atom O2 = new Atom(water);
}
}
}
namespace-Yesod
{
公共课程
{
//
//
//
公共结构粒子
{
公共字节类型;
}
//用C#4.0使用out关键字进行修复。
//
//
公共界面的开放性
{
亲本
{get;}
}
//
//
//
公共类实体:通用性
{
公母
{get;私有集;}
//
//
//
公共实体(企业母公司)
{
这个。父=父;
}
}
//
//
//
公共密封类Atom:实体
{
公共原子(实体父级)
:base(parent)//不再有编译错误。
{ }
}
//
//
//
公共密封类分子:实体
{
公共分子()
:base(空)
{ }
}
//
//