C#中的多重继承 [英] multi inheritation in c#

查看:68
本文介绍了C#中的多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个项目管理系统,WBS结构是其核心功能之一.

我将Node定义为抽象类,将TreeNode类和SensitiveNode类定义为Node的子类. TreeNode重设树形结构的节点,SensitiveNode重设节点可在客户端访问它时进行验证和记录的节点.如果我想要一个同时共享TreeNode和SensitiveNode行为的SensitiveTreeNode怎么办?如何设计类SensitiveTreeNode.

因为TreeNode和SensitiveNode有点复杂,所以我不想在SensitiveTreeNode中重写代码,因为这会导致维护灾难.

我认为多重继承在现实世界中非常普遍,人们通常会使用哪种方案.

I''m designing a project management system, and the WBS structure is one of the core functions.

I define Node as a abstract class, TreeNode class and SensitiveNode class as a subclass of Node. TreeNode reprensets a node of a tree structure, SensitiveNode reprensets a node which can do validate and log when client access it. What if I want a SensitiveTreeNode which share the behavior of both TreeNode and SensitiveNode? How can I design the class SensitiveTreeNode.

Because TreeNode and SensitiveNode is kind of complex, I don''t want rewrite code in SensitiveTreeNode, because it would cause maintain disaster.

I think multi inheritation is very common in real world, what do people deal with those kind of scenarious normally.

推荐答案

如果这两种操作都很复杂并且不能如果安排在单个继承层次结构中,则应该撰写而不是继承.将每个部分的主要特征都提取到提供程序类中,因此
If both operations are complex and can''t be arranged into a single inheritance hierarchy, you should compose, not inherit. Take out the main features of each part into a provider class, so
class SensitiveTreeNode : SensitiveNode, TreeNode {
 public void SomeSensitiveMethod(string arg) { ... }
 public TreeNode Parent { get; set; }
}



...变成:



... becomes:

class SensitiveTreeNode : Node, ISensitiveNode, ITreeNode {
 public TreeNodeProvider TreeProvider {get; private set; }
 public SensitivityProvider SensitivityProvider { get; private set; }

 SensitiveTreeNode() {
  TreeProvider = GetTreeNodeProvider();
  SensitivityProvider = GetSensitivityProvider();
 }

 virtual TreeNodeProvider GetTreeNodeProvider() { return new TreeNodeProvider(this); }
 virtual SensitivityProvider GetSensitivityProvider() { return new SensitivityProvider(this); }
}

class TreeNodeProvider {
 ITreeNode host;
 
 public ITreeNode Parent { get; set; }
 
 public TreeNodeProvider(ITreeNode host) { this.host = host; }
}

class SensitivityProvider {
 ISensitiveNode host;
 
 public void SomeSensitiveMethod(string arg) { ... }

 public SensitivityTreeNodeProvider(ISensitiveNode host) { this.host = host; }
}

interface ISensitiveNode {
 SensitivityProvider SensitivityProvider { get; }
}

interface ITreeNode {
 TreeNodeProvider TreeProvider { get; }
}



提供者从本质上来说是相当笼统的,因为它们将为任何树或敏感节点提供功能.如果需要特定节点类的特殊实现,则可以创建一个嵌套类,该嵌套类继承自适当的基本提供程序类,并将其分配给提供程序属性.

这意味着所有对树节点或敏感节点方法和属性的调用都会在其中获得额外的文本:
myTreeNode.TreeProvider.Parent = myOtherTreeNode;
...而且工作量很大,因此并不完美.不过,这是在C#(或Java或其他单一继承语言)中可以合理地完成的,与继承两件事最接近的事情– SensitiveTreeNode现在确实提供了两组功能,并且都是可继承的,多态的(通过重写).提供程序类和GetXxxProvider方法).

该答复的长度强调了,如果完全合理的话,您应该如何尝试至少安排主继承层次结构,以使您不需要多重继承.以您的示例为例,通常希望将节点绑定到特定的数据结构.我希望您可以使TreeNode成为基类并具有从其继承的敏感性. (当前不在树中的节点可以只是一个空树/父节点.)但是显然我们没有您的问题的详细信息,这可能不合适.



The providers are by their nature fairly general, as they will provide functionality for any tree or sensitive node. If you want a special implementation for a particular node class, you can create a nested class which inherits from the appropriate base provider class, and assign that to the provider property.

This means that all calls to tree node or sensitive node methods and properties get an extra bit of text in them:
myTreeNode.TreeProvider.Parent = myOtherTreeNode;
... and it''s quite a bit of work, so it''s not perfect. It is the closest thing that can reasonably be done in C# (or Java or other single-inheritance languages) to inheriting two things, though – SensitiveTreeNode now really does provide two sets of functionality, and it is all inheritable, polymorphic etc (through overriding provider classes and GetXxxProvider methods).

The length of this reply emphasises how, if it is at all reasonable, you should try to make at least your main inheritance hierarchy be arranged so that you don''t need multiple inheritance. In the case of your example, nodes are usually expected to be bound to a particular data structure; I would expect that you could make TreeNode be a base class and have sensitivity inherit from it. (Nodes not currently in a tree can simply have a null tree/parent.) But obviously we don''t have the details of your problem and that may not be appropriate.


您可以遵循基于接口的设计.

TreeNode继承Node
SensitiveNode继承Node

将ITreeNode定义为TreeNode的接口,并将ISensitiveNode定义为SensitiveNode的接口.

然后,您可以定义新的SensitiveTreeNode类来删除rom Node并实现ITreeNode和ISensitiveNode.

我将把SensitiveTreeNode的实现细节留给您.
一种选择是在SensitiveTreeNode中使用TreeNode和SensitiveNode的组合或一个干净的实现,这应该由您的要求来驱动.
In these situations you can follow Interface based design.

TreeNode inherits Node
SensitiveNode inherits Node

Define ITreeNode as the interface for TreeNode and ISensitiveNode as interface for SensitiveNode.

Then, You can define the new class SensitiveTreeNode to derieve rom Node and implement ITreeNode and ISensitiveNode.

I would leave the implementation details of SensitiveTreeNode to you.
One of the option is to use composition of TreeNode and SensitiveNode in SensitiveTreeNode or a clean implementation, which should be driven by your requirement.


我会感觉到您的痛苦:就像在Java中(与C++相对),您不能在C#中具有多重继承(很多人认为它是C#的一项功能,而不是限制...).
常见的转义可能是从较复杂的类继承而实现较不复杂的类(应成为接口).
I can feel your pain: like in Java (and opposite to C++), you cannot have multiple inheritance in C# (and many many folks here think it''s C# a feature, not a limitation...).
The common escape is probably inheriting from the more complex class and implementing the less complex (that should become an interface).


这篇关于C#中的多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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