Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基类包含对其子类之一的引用可以吗?_C#_Coding Style - Fatal编程技术网

C# 基类包含对其子类之一的引用可以吗?

C# 基类包含对其子类之一的引用可以吗?,c#,coding-style,C#,Coding Style,我编写了以下类来创建树层次结构,但由于所有节点类都包含类型为ParentNode的父节点,因此我希望将其移动到基类中,以便不必为所有节点类型重写与父节点相关的任何代码。因此,虽然它显然有效,但在节点库-类中有一个类型为ParentNode的字段会被认为是不好的做法吗?如果是,解决这个问题的“正确”方法是什么 公共抽象类节点库{ /*各种通用方法和性质*/ } 公共类ParentNode:节点库{ 公共只读父节点父节点; 公共只读列表子项; /*与父节点相关的方法等*/ } 公共类LeafNode

我编写了以下类来创建树层次结构,但由于所有节点类都包含类型为
ParentNode
的父节点,因此我希望将其移动到基类中,以便不必为所有节点类型重写与父节点相关的任何代码。因此,虽然它显然有效,但在
节点库
-类中有一个类型为
ParentNode
的字段会被认为是不好的做法吗?如果是,解决这个问题的“正确”方法是什么

公共抽象类节点库{
/*各种通用方法和性质*/
}
公共类ParentNode:节点库{
公共只读父节点父节点;
公共只读列表子项;
/*与父节点相关的方法等*/
}
公共类LeafNode:NodeBase{
公共只读父节点父节点;
/*与叶节点相关的方法等*/
}

我不能将
公共只读NodeBase父节点
放在
NodeBase
-类中,因为
NodeBase
没有
子节点
-列表,并将
子节点
放在那里,会导致<代码>叶结< /代码> s也有那个列表。

虽然我不认为它是坏的实践,但它会告诉我,我设计了一些错误。 一般来说,在超类中保留子类的引用没有任何意义


在这种情况下,我不明白为什么需要为叶节点和父节点创建单独的类。所有节点都可以有子节点和父节点。作为叶节点只是没有子节点的结果,任何只影响叶节点的方法都可以检查列表的计数以确认不存在子节点。就像任何根节点检查都会查看父节点。

虽然我不认为它是坏的实践,但它会告诉我,我设计了一些错误。 一般来说,在超类中保留子类的引用没有任何意义


在这种情况下,我不明白为什么需要为叶节点和父节点创建单独的类。所有节点都可以有子节点和父节点。作为叶节点只是没有子节点的结果,任何只影响叶节点的方法都可以检查列表的计数以确认不存在子节点。就像任何根节点检查都会检查父节点一样。

此模式经常使用,没有任何问题

乍一看,这似乎有点像一个循环依赖,但这并没有真正的问题。因此,当您需要(想要)对一种特殊类型的派生节点的引用时,您可以并且应该准确地对其建模。比使用更通用的
节点库父节点{get;set;}
然后将其用于类型转换和额外检查要好得多,也更安全

这很常见,例如在课堂上:


这种模式经常使用,没有什么问题

乍一看,这似乎有点像一个循环依赖,但这并没有真正的问题。因此,当您需要(想要)对一种特殊类型的派生节点的引用时,您可以并且应该准确地对其建模。比使用更通用的
节点库父节点{get;set;}
然后将其用于类型转换和额外检查要好得多,也更安全

这很常见,例如在课堂上:


你为什么需要它?您可以通过多态性解决父级的需求。原则。@SriramSakthivel:我在那里不需要它,我只想将它移到那里,这样我就可以在基类中编写与父类相关的任何代码,而不是在每个子类中重复它。您可以将
NodeBase
中的方法添加为虚拟方法,并在
ParentNode
类中重写它,并访问那里的
父类和子类。我认为这是相关的。@Closer:这根本不是“基于意见的”。从技术上讲,你不应该这么做,因为通常我们想要的是不耦合的系统,或者更确切地说,我们尽量减少耦合。我个人不认为这是个好主意你为什么需要它?您可以通过多态性解决父级的需求。原则。@SriramSakthivel:我在那里不需要它,我只想将它移到那里,这样我就可以在基类中编写与父类相关的任何代码,而不是在每个子类中重复它。您可以将
NodeBase
中的方法添加为虚拟方法,并在
ParentNode
类中重写它,并访问那里的
父类和子类。我认为这是相关的。@Closer:这根本不是“基于意见的”。从技术上讲,你不应该这么做,因为通常我们想要的是不耦合的系统,或者更确切地说,我们尽量减少耦合。我个人认为这不是一个好主意,“这会向我表明我设计了一些错误的东西。”是的,这正是我得到的感觉,但我真的不知道如何设计它来解决问题。我希望为叶节点创建一个单独的类的原因是为了进一步降低复杂性。刚开始时,我只有一种类型的节点,但该方法在调用
IsRoot
IsLeaf
等时变得非常混乱。不,这并不是错误的或不常见的。参见示例
XObject.Parent
,类型为
XElement:XObject
@HenkHolterman谢谢您的示例。既然这个问题已经结束了,我现在就开始在
BaseNode
中添加一个
ParentNode
。如果它再次打开,可以随意张贴一个更详细的例子/解释作为答案,“它会告诉我我设计了一些错误。”是的,这正是我得到的感觉,但我不知道如何设计它来解决问题。我希望为叶节点创建一个单独的类的原因是为了进一步降低复杂性。刚开始时,我只有一种类型的节点,但该方法在调用
IsRoot
IsLeaf
public abstract class NodeBase{
    /*Various general methods and properties*/
}
public class ParentNode : NodeBase{
    public readonly ParentNode Parent;
    public readonly List<NodeBase> Children;

    /*Methods etc related to parent nodes*/
}
public class LeafNode : NodeBase{
    public readonly ParentNode Parent;

    /*Methods etc related to leaf nodes*/
}
class XObject
{
   public XElement Parent { get; }
   public XDocument Document { get; }
}

class XElement  : XObject { ... }   // with a few classes 
class XDocument : XObject { ... }   //    in between