如何强制实现多个构造函数

发布于 2024-07-24 02:24:34 字数 2419 浏览 1 评论 0原文

我正在创建一个基类Node,它本质上包装了我正在为其编写插件的程序BaseAppObject中的另一个类的实例。 Node 的属性以及 Node 的任何派生都通过 BaseAppObject.SetUserString(key,value)两种方法将其属性存储在 BaseAppObject 中BaseAppObject.GetUserString(键,值)

有两种情况我需要实例化一个节点。 其中 BaseAppObject 是干净的,并且没有用户字符串。 在这种情况下,需要向构造函数传递所有要启动的属性的值。 第二个是当我有一个已经定义了用户字符串的 BaseAppObject 时,我只想用 Node 对象包装它。 在这种情况下,我只需要运行设置 _baseObject 字段的初始化构造函数。 然后,该对象的所有其他属性都将从 BaseAppObject 中设置的用户字符串中读取。

这是我的课程的简化版本。

public abstract class Node
{
    BaseAppObject _baseObject;

    //reinitializing constructor
    public Node(BaseAppObject baseObject)
    {
         this._baseObject = baseObject;
    }

    //initializing constructor
    public Node(BaseAppObject baseObject, string name)
    {
        this._baseObject = baseObject;
        this.Name = name;
    } 

    public string Name
    {
        get { 
                string name = "";
                _baseObject.GetUserString("CPName", ref name);
                return name;             
            }

        set {
                _baseObject.SetUserString("CPName", value);
            }
    }
}

Node 派生的其他类可能会添加类似这样的附加属性。

public CustomClass:Node
{

    //reinitializing constructor
    public CustomClass(BaseAppObject baseObj):base(baseObj)
    {
    }


    //initializing constructor
    public CustomClass(BaseAppObject baseObj,string name, string color):base(baseObj,name)
    {

        //here's an additional property added to CustomClass
        public string Color
        {
            get { 
                    string name = "";
                    this.BaseObject.GetUserString("Color", ref name);
                    return name;             
                }
            set {
                    this.BaseObject.SetUserString("Color", value);
                }
        }
}

这是可行的,但稍后如果我(或其他人)想要从 Node 派生另一个类,他们必须了解派生类需要有两个构造函数。 一个用于初始化,另一个用于重新初始化。

有没有办法让这个实现成为 Node 类的内在实现? 或者完整的文档是唯一的选择吗?

还有一种方法可以避免在从节点派生的每个类中放置相同的单参数构造函数(如下)。

//reinitializing constructor
public ClassDerivedFromNode(BaseAppObject baseObject)
{
     this._baseObject = baseObject;
}

I'm creating a base class Node that essentially wraps instances of another class from a program I am writing a plugin for, BaseAppObject. Properties of Node and any derivation of Node store their properties in the BaseAppObject through two methods BaseAppObject.SetUserString(key,value) and BaseAppObject.GetUserString(key,value).

There are two situations where I need to instantiate a Node. One where the BaseAppObject is clean, and has no user strings. In this case the constructor needs to be passed the values of all the properties to initiate. The second is when I have a BaseAppObject that already has user strings defined and I simply just want to wrap it with a Node object. In that case I only need to run the initialization constructor that sets the _baseObject field. All other properties of the object will then simply read from user strings set in the BaseAppObject.

Here's a simplified version of what my classes look like.

public abstract class Node
{
    BaseAppObject _baseObject;

    //reinitializing constructor
    public Node(BaseAppObject baseObject)
    {
         this._baseObject = baseObject;
    }

    //initializing constructor
    public Node(BaseAppObject baseObject, string name)
    {
        this._baseObject = baseObject;
        this.Name = name;
    } 

    public string Name
    {
        get { 
                string name = "";
                _baseObject.GetUserString("CPName", ref name);
                return name;             
            }

        set {
                _baseObject.SetUserString("CPName", value);
            }
    }
}

Other classes derived from Node may add additional properties like this.

public CustomClass:Node
{

    //reinitializing constructor
    public CustomClass(BaseAppObject baseObj):base(baseObj)
    {
    }


    //initializing constructor
    public CustomClass(BaseAppObject baseObj,string name, string color):base(baseObj,name)
    {

        //here's an additional property added to CustomClass
        public string Color
        {
            get { 
                    string name = "";
                    this.BaseObject.GetUserString("Color", ref name);
                    return name;             
                }
            set {
                    this.BaseObject.SetUserString("Color", value);
                }
        }
}

This works, but later on if I (or someone else) wants to make another class derived from Node they have to understand that the derived class needs to have two constructors. One for initialization and another for reinitialization.

Is there some way to make this implementation intrinsic to the Node class? Or is thorough documentation the only option?

Also is there a way to avoid placing the same single argument constructor (below) in every class derived from node.

//reinitializing constructor
public ClassDerivedFromNode(BaseAppObject baseObject)
{
     this._baseObject = baseObject;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

安静 2024-07-31 02:24:34

您可能需要考虑使用工厂方法作为问题的解决方案。

You might want to consider Factory Methods as a solution to your problem.

原来分手还会想你 2024-07-31 02:24:34

没有办法强制子类创建两个构造函数。 文档和代码审查很有用,但并非万无一失。 否则,您可能必须在构造函数中添加检查,以确保在调用重新初始化构造函数时设置“CPName”属性,否则抛出异常。 或者,您可以执行 Debug.Assert 而不是抛出异常。

There's no way to force subclasses to create two constructors. Documentation and code reviews are useful, but not foolproof. Otherwise, you might have to add checks in the constructor to ensure that the "CPName" property is set if the reinitialize constructor is called and throw an exception if it's not. Alternately, you can do a Debug.Assert instead of throwing an exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文