Reputation: 6025
I have this generic class Foo<>
with two constructors. One of them accepts variable number of parameters using params
keyword. The other nongeneric class Bar
is derived from Foo<>
. The problem is that Bar
does not accept instantiating with constructor that hasparams
.
This is a sample:
using System;
namespace ConsoleApp1
{
class Foo<T> where T : IComparable<T>
{
private Foo() { }
public Foo(params T[] list) : this() { }
}
class Bar : Foo<int> { }
class Program
{
static void Main(string[] args)
{
Foo<int> foo = new Foo<int>(1, 2); // it compiles
Bar bar = new Bar(1, 2); // but CS1729 here!
}
}
}
It gives a compiler error:
Error CS1729: 'Bar' does not contain a constructor that takes 2 arguments
What am I missing here?
Upvotes: 0
Views: 347
Reputation: 42360
Constructors aren't inherited in C#. If you don't specify a constructor, the compiler will generate a parameterless constructor for you, which calls the base class's parameterless constructor. If your class derives from a base class which doesn't have any non-private parameterless constructors, the compiler errors.
So your plan of getting Bar
to inherit the Foo
constructor which takes a params T[]
will never work.
It turns out that what's happening here is that the compiler has realised that it can generate a parameterless constructor which calls the base Foo(params T[])
constructor, by passing an empty array. See it here.
In your case, you need to give Bar
its own constructor:
class Bar : Foo<int>
{
public Bar(params int[] list) : base(list) { }
}
Upvotes: 2
Reputation: 14710
This has nothing to do with generics. It's just that constructors are not, by default, inherited in child classes. The fact that Foo<int>
has a params int[]
constructor doesn't automatically mean Bar
has it too:
Not all members of a base class are inherited by derived classes. The following members are not inherited:
- Instance constructors, which you call to create a new instance of the class. Each class must define its own constructors.
(from the C# Inheritance Tutorial on MS Docs)
You'll have to define a specific constructor for Bar
and chain the base call to it:
public Bar (params int[] list) : base(list) {}
Upvotes: 2
Reputation: 1553
You are missing implementing that constructor from Foo
in Bar
:
class Foo<T> where T : IComparable<T>
{
private Foo() { }
public Foo(params T[] list) : this() { }
}
class Bar : Foo<int>
{
public Bar(params int[] list) : base(list) { }
}
Upvotes: 3