简体   繁体   中英

How to create an abstract constructor or get type of abstract class and return it?

I can't get the method or a constructor inside of my abstract class working correctly.

I essentially have several data contract classes that extend my abstract class and have a simple, nearly identical method inside of them that I'm trying to figure out how to move to my abstract class.

I'm pretty sure a constructor makes the most sense, but I can't figure out the proper syntax. To use it currently, I call something like this:

OrderLine orderLine = new OrderLine();

orderLine = orderLine.createFromJsonString("MyJsonString");

I'm trying to move the methods marked (1) and (2) into the (0) position as either a method or constructor.

abstract class Pagination<T>
{
    public int _offset { get; set; }
    public int _total { get; set; }
    public string previous { get; set; }
    public string next { get; set; }
    public abstract List<T> items { get; set; }

    public int getItemCount()
    {
        return items != null ? items.Count() : 0;
    }

    // (0)
    // Each of the child objects that extend this class are created from
    // a Json that is deserialized. So I'd rather some method that would
    // construct or return a new instance of the abstract object 
    /*
    public object createFromJsonString(string _json)
    {
     * // The main issue here is the "this" keyword
        return JsonConvert.DeserializeObject<this>(_json);
    }
     **/

}

class OrderHeader : Pagination<OrderLine>
{
    public int orderId { get; set; }
    public List<OrderLine> items { get; set; }

    // (1)
    // How can I move this into the abstract class?
    // Or should it be written as constructor?
    public OrderHeader createFromJsonString(string _json)
    {
        return JsonConvert.DeserializeObject<OrderHeader>(_json);
    }
}

class OrderLine : Pagination<OrderLineDetails>
{
    public string sku { get; set; }
    public int qty { get; set; }
    public List<OrderLineDetails> items { get; set; }

    // (2)
    // How can I move this into the abstract class?
    // Or should it be written as constructor?
    public OrderLine createFromJsonString(string _json)
    {
        return JsonConvert.DeserializeObject<OrderLine>(_json);
    }
}

class OrderLineDetails
{
    public string serialNum { get; set; }
}

Here you are doing few things incorrectly:

// You have created object once here, this object would become unused in next line
OrderLine orderLine = new OrderLine();

// Here you are building a new object via Deserialize
orderLine = orderLine.createFromJsonString("MyJsonString");

What I understood from your question is you want to have a factory method to create objects of derived types of Pagination<>.

abstract class Pagination<T>
{
    public int _offset { get; set; }
    public int _total { get; set; }
    public string previous { get; set; }
    public string next { get; set; }
    public abstract List<T> items { get; set; }

    public int getItemCount()
    {
        return items != null ? items.Count() : 0;
    }

    /// <summary>
    /// Factory method to build the pagination object from Json string.
    /// </summary>
    public static TCurrent CreateFromJsonString<TCurrent>(string _json) where TCurrent: Pagination<T>
    {
        return JsonConvert.DeserializeObject<TCurrent>(_json);
    }
}

Now you can build the object of Derived types like:

 OrderHeader hdr = Pagination<OrderLine>.CreateFromJsonString<OrderHeader>(json);

 OrderLine line = Pagination<OrderLineDetails>.CreateFromJsonString<OrderLine>(json);

The factory method also prevent doing something like below because we have applied generic constraints so that only relevant items types are allowed.

// This will throw error of invalid implicit conversion
OrderHeader invalidObj = Pagination<OrderLineDetails>.CreateFromJsonString<OrderHeader>(json);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM