Eric Anastas
Eric Anastas

Reputation: 22213

What is the correct way to write a constructor for a wrapper class?

I'm writing a plugin for an application with a .NET API. The objects of the program can have custom attributes applied through two methods of the root object type which assign key/value pairs to the objects.

BaseAppObject.GetUserString(string key, string value);
BaseAppObject.SetUserString(string key, ref string value);

I'm creating a set of my own custom classes that act as wrapper classes around instances of BaseAppObject. All my classes are derived from a class Node which has a field to store a reference to a BaseAppObject. Other properties of Node and types that derive from Node use the GetUserString and SetUserString methods of the associated BaseAppObject instance to read or write property values directly to or from the associated BaseAppObjects.

This way when the application is closed all the information needed to regenerate these wrapper classes later is stored in the actual document.

Here's a simplified version of what I have for my base class constructor:

public abstract class Node
{
    BaseAppObject _baseObject;

    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
{
    public CustomClass(BaseAppObject baseObj,string name, string color):base(baseObj,name)

    public string Color
    {
        get { 
                string name = "";
                this.BaseObject.GetUserString("Color", ref name);
                return name;             
            }

        set {
                this.BaseObject.SetUserString("Color", value);
            }
    }
}

I'm trying to figure out the best way to setup the constructors and other methods of my classes to initiate and regenerate instances of my classes. I need to be able to create new instances of my classes based of clean instances of BaseAppObject that have no user strings defined, and also regenerate previously existing instance of my class based on the user strings stored in a existing BaseAppObject.

Upvotes: 0

Views: 2148

Answers (3)

Robert Harvey
Robert Harvey

Reputation: 180788

It looks like you have already figured out how to regenerate previously existing classes. To generate a clean object with no values, all you have to do is provide an additional overload that takes no parameters and creates _baseObject. Once the object is created in this manner, you can use it's properties to set the member values.

public abstract class Node
{
    BaseAppObject _baseObject;
    //Empty constructor
    public Node() 
    {
        BaseAppObject = new BaseAppObject();
    }
    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);
            }
    }
}

public CustomClass:Node
{
    // Empty constructor
    public CustomClass() : Base() {}
    public CustomClass(BaseAppObject baseObj,string name, string color):base(baseObj,name)

    public string Color
    {
        get { 
                string name = "";
                this.BaseObject.GetUserString("Color", ref name);
                return name;             
            }

        set {
                this.BaseObject.SetUserString("Color", value);
            }
    }
}

Sample code for creating an empty object and populating it:

CustomClass node = new CustomClass();
node.Name = "foo";
node.Color = "bar";

Upvotes: 1

skyronic
skyronic

Reputation: 1635

I don't see why you don't want to make Node a child class of BaseClassObj. If you're writing a wrapper class, you can use the type-casting features to make your "Node" class and all it's children directly compatible with the BaseClassObj.

If you're doing that, you can just say

public abstract class Node : BaseAppObject
{

    public Node(string name) : base()
    {            
        this.Name = name;
    } 

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

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

Now you can use a Node object just like a BaseClassObj, and still use the additional functionality. I think this is a better way to implement a wrapper class. The typecasting in C# is fantastic and you should take advantage of it.

Upvotes: 0

zonkflut
zonkflut

Reputation: 3037

I have written a base Wrapper Object that I have all my wrappers inherit from.

public abstract class BaseWrapper<TBaseType> 
    where TBaseType : class
{
    protected readonly TBaseType BaseItem;

    protected BaseWrapper(TBaseType value)
    {
        BaseItem = value;
    }

    public bool IsNotNull()
    {
        return BaseItem != null;
    }
}

Upvotes: 1

Related Questions