N3wbie
N3wbie

Reputation: 227

C# need explanation on new constraint (new T(...))

The following Code returns an error:

private void HandleBookLogic<T>() where T : Book , new()
{
    LibraryList.Items.Add(new MyItems(new T(int.Parse(copyNumber.Text), 
                                        itemName.Text, 
                                        DateTime.Parse(TimePrinted.Text), 
                                        int.Parse(Guid.Text), 
                                        (JournalCategory)Enum.Parse(typeof(JournalCategory), 
                                        Category.Text))));
}

'T' cannot provide arguements when creating an instance of Variable Type

I have 3 classes with generic usage: reading\cooking\science

MyItems is the class that responsible for the XAML bindings to the ListView (doesn't matter right now). Each one of the 3 classes gives me an error as well:

'Reading' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ItemWindow.HandleBookLogic()

I'm very fresh to C#, I kind of "understand" the errors but do not know how to handle them.

Appreciate the help.

EDIT: Extra code:

private void Add_Click(object sender, RoutedEventArgs e)
{

    if (Type.Text == "Journal")
    {
        HandleJournalLogic();
    }
    else
    {
        if (Type.Text == "Reading")
            HandleBookLogic<Reading>();
        else if (Type.Text == "Cooking")
            HandleBookLogic<Cooking>();
        else
        {
            HandleBookLogic<Science>();
        }
    }
    InitFields();
}

Can someone fix my code so I can learn of it?

Upvotes: 2

Views: 88

Answers (1)

Daniel Pryden
Daniel Pryden

Reputation: 60957

The new constraint is only for a parameterless constructor. If you need a constructor that takes arguments then your caller needs to tell you how to construct instances. One common approach is for your method to take a factory delegate as an argument.

For example, you could take a Func<int, T> for a constructor that takes an int; the caller can supply the function using a lambda.

If you know the exact constructor signature you could also use reflection or else dynamic. Those options will both be a lot slower than passing a delegate, though. Depending on your needs that may not be a problem.

Upvotes: 3

Related Questions