我很ham愧地承认我在这个问题上坐了很多小时。但是我只想按照下图中的结构来实现它。...
我想用其中的大洲/国家/州和城市来模拟世界。每个模型都有其父对象的引用和其子对象的引用列表,但世界上只有子对象(因为不能有父对象),而城市仅具有父对象引用,因为它没有深入。 (我想实现它,例如“世界”没有父字段,同样,“城市”也没有List<Children>
字段。
为了让您了解接口的代码,我在此处包括了最少的内容:
public interface IRoot<TChild>
{
List<TChild> Children { get; set; }
void AddChild(TChild child);
}
public interface ILeaf<TParent>
{
TParent Parent { get; set; }
}
public interface INode<TParent, TChild> : IRoot<TChild>, ILeaf<TParent> { }
以及一些实施代码:
public class Root<TChild> : IRoot<TChild>
{
public List<TChild> Children { get; set; }
public void AddChild(TChild child) { //... }
}
public class Leaf<TParent> : ILeaf<TParent>
{
public TParent Parent { get; set; }
}
public class Node<TParent, TChild> : INode<TParent, TChild>
{
private IRoot<TChild> root;
private ILeaf<TParent> leaf;
//...
}
最后,我要构建的类的代码:
public class World : Root<Continent> { }
public class Continent : Node<World, Country> { }
public class Country : Node<Continent, State> { }
public class State : Node<Country, City> { }
public class City : Leaf<City> { }
这是问题所在:
现在要在Root<TChild>.AddChild(TChild)
中添加子对象,我需要访问<TChlid>.Parent
,因此需要像这样将通用TChild
约束为ILeaf<IRoot<TChild>>
:
public class Root<TChild> : IRoot<TChild> where TChild : ILeaf<Root<TChild>>
{
public void AddChild(TChild child)
{
child.Parent = this;
}
}
但是这样做,我得到了错误
CS0311 C#该类型不能用作通用类型或方法中的类型参数。没有从到的隐式引用转换。
在这一行
public class World : Root<Continent> { }
答案 0 :(得分:0)
最后,我找到了解决方案。它包括使基类Root<TChild>
和Node<TParent, TChild>
抽象。设置孩子的父母将被委托给一个抽象方法。在解决了通用类型参数的具体实现中,访问Parent
属性是没有问题的。
我也略微更改了界面。将孩子暴露为List<TChild>
是有问题的,因为它允许任何人通过直接添加到列表中来绕开AddChild
的添加逻辑,而忘记设置孩子的父母。
我也将接口中的Parent
属性设为只读,因为设置器仅在实现中使用。
public interface IRoot<TChild>
{
IReadOnlyList<TChild> Children { get; }
void AddChild(TChild child);
}
public interface ILeaf<TParent>
{
TParent Parent { get; }
}
public interface INode<TParent, TChild> : IRoot<TChild>, ILeaf<TParent>
{
}
基类:
public abstract class Root<TChild> : IRoot<TChild>
{
private List<TChild> _children = new List<TChild>();
public IReadOnlyList<TChild> Children => _children;
public void AddChild(TChild child)
{
_children.Add(child);
SetChildsParent(child);
}
protected abstract void SetChildsParent(TChild child);
}
public class Leaf<TParent> : ILeaf<TParent>
{
public TParent Parent { get; internal set; }
}
public abstract class Node<TParent, TChild> : Root<TChild>, INode<TParent, TChild>
{
public TParent Parent { get; internal set; }
}
请注意,Node
是从Root
继承的,因此我们仅需补充ILeaf
的实现。
具体的实现类:
public class World : Root<Continent>
{
protected override void SetChildsParent(Continent child) => child.Parent = this;
}
public class Continent : Node<World, Country>
{
protected override void SetChildsParent(Country child) => child.Parent = this;
}
public class Country : Node<Continent, State>
{
protected override void SetChildsParent(State child) => child.Parent = this;
}
public class State : Node<Country, City>
{
protected override void SetChildsParent(City child) => child.Parent = this;
}
public class City : Leaf<State> { }