Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Must be a non abstract type with public parameterless constructor

I read the answers to some similar questions to mine but couldn't find a good explanation to my case. Please, correct me, if I'm wrong :)

I have three classes - a base abstract class, called EmailData, and two other classes that derive from the base class. I have not included one of the inheriting classes and most of the members of the other classes to make the example more obvious.

private abstract class EmailData
    {
        public EmailData(DataRow emailDataRow)
        {
            vehicleOwner = emailDataRow["owner"].ToString();
        }

        public string VehicleOwner { get { return vehicleOwner; } }

        private string vehicleOwner;
    }

    private class DeliveryEmailData : EmailData
    {
        public DeliveryEmailData(DataRow deliveryData)
            : base(deliveryData)
        {
            orderNumber = deliveryData["ordernumber"].ToString();
        }

        public string OrderNumber { get { return orderNumber; } }

        private string orderNumber;
    }

I have a generic class, that uses one of the two classes that derive from the base class EmailData, and looks like this:

private class Email<T> where T : EmailData, new()
    {
        public Email(DataTable emailDataTable)
        {
            // Get the number of rows.
            int rowsNumber = emailDataTable.Rows.Count;

            emailsData = new T[rowsNumber];

            for (int i = 0; i < rowsNumber; i++)
            {
                // Store the appropriate data in the arrays.
                emailsData[i] = (T)Activator.CreateInstance(typeof(T), emailDataTable.Rows[i]);
            }

            // Get the email of the recipient.
            recipientEmail = emailDataTable.Rows[0]["delivery_email"].ToString();
        }

        public T[] EmailsData { get { return emailsData; } }
        public string RecipientEmail { get { return recipientEmail; } }

        private T[] emailsData;
        private string recipientEmail;
    }

If I decide to make a new instance of the Email class:

Email<DeliveryEmailData> email = new Email<DeliveryEmailData>(someDataTableObject);

I get the following error:

'DeliveryEmailData' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T'

When I add a parameterless constructor to both the base and derived classes, the error no longer shows up. The problem is that I don't need a parameterless constructor, but one that receives a DataTable object.

So, does anyone know what is wrong with this?

like image 537
Yulian Avatar asked Apr 06 '14 11:04

Yulian


1 Answers

You have constrained T as T : new() which meant it must be non-abstract i.e. you must be able to create instance of type T and it must have parameterless constructor. The problem not in

public Email(DataTable emailDataTable){}

which receives DataTable but in

public EmailData(DataRow emailDataRow){}

you can remove constraint new() to solve your problem.

like image 100
Hamlet Hakobyan Avatar answered Nov 10 '22 06:11

Hamlet Hakobyan