90

Is it possible to add a constructor extension method?

Sample Use Case

I want to add a List< T > constructor to receive specific amount of bytes out of a given partially filled buffer (without the overhead of copying only the relevant bytes and so on):

...
public static List<T>(this List<T> l, T[] a, int n)
{
    for (int i = 0; i < n; i++)
       l.Add(a[i]);
}
...

so the usage would be:

List<byte> some_list = new List<byte>(my_byte_array,number_of_bytes);

I've already added an AddRange extension method:

public static void AddRange<T>(this List<T> l, T[] a, int n)
{
   for (int i = 0; i < n; i++)
       l.Add(a[i]);
}

I want to do it as a constructor too. Is it possible? If yes - how?

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Tar
  • 8,529
  • 9
  • 56
  • 127

5 Answers5

59

No, but if you changed your AddRange signature to return the list instance, then you could at least do

var list = new List<int>().AddRange(array, n);

which imho is probably clearer than overloading the constructor anyway.

fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253
  • Great! I missed that possibility - that's exactly what I was looking for! – Tar Jan 26 '11 at 06:52
  • Great alternative! I used your example to add an Initialize method to a DataColumn object. I suppose .AnEvenBetterConstructor(...) would have been too much. – Greg Biles Jul 12 '11 at 01:20
42

SWeko's answer is basically correct, though of course the article he links to is about extension properties rather than extension constructors.

We also did a rough design for extension constructors at the same time as we did extension properties; they would be a nice syntactic sugar for the factory pattern. However, they never got past the design stage; the feature, though nice, is not really necessary and does not enable any awesome new scenarios.

If you have a really awesome problem that extension constructors would solve, I'd be happy to hear more details. The more real-world feedback we get, the better we are able to evaluate the relative merits of the hundreds of different feature suggestions we get every year.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Hi Eric. There is an example here that I have. Don't know if tis good but... I got more than 50 classes from Silverlight 2.0 that I have to convert to WPF 4.0. The class WriteableBitmap has a constructor that is really different. A lot more complex in WPF but that where we could fix every 4 new parameters. By having the possibility to create (overrride) a new constructor, then we would be able to save us a lots of code re-write. Thanks. – Eric Ouellet Mar 05 '12 at 17:24
  • It would be really useful to constructor extend `string` so it could work with `default(string)`. Either that or provide a default constructor for `string`. – Thomas Eding Jul 25 '12 at 21:56
  • 6
    I realize that I am bringing a zombie back to life, but one place where it would be very useful to have construct extensions is for exceptions. I would like to replace the message parameter in most extensions with an overload that takes a format and params object[] arguments, so that I do not need to explicatly call string.Format() to create the message. – David Williams Jun 07 '13 at 16:42
  • This feature could help, by providing a common initialization point for all classes that inherit a base class. For example, `Spec1` and `Spec2` inherit from the `Base` abstract class (all are classes you cannot modify (compiled assembly for instance)). By adding a parameterless extension constructor to `Base` (as well as extension properties/methods), one could provide initialization logic for both `Spec1` and `Spec2` in a single extension constructor. – ken2k Jul 01 '13 at 13:35
  • I extracted this use case from a real world scenario: I wanted to create a base class for some of my Entity Framework entities, and add some initialization stuff for all of them using a single extension constructor. – ken2k Jul 01 '13 at 13:38
  • Similar to @DavidWilliams to avoid creating a custom exception to throw when the `default:` clause is hit in a switch, I wanted to extend the `InvalidOperationException` constructor to create a well formatted and useful message. A few overloads of the exception constructor (extensions) could handle strings, enums, etc. based parameter names and values with only one location for the implementation details instead of in each `default:` clause. – HodlDwon Oct 11 '13 at 17:01
  • I found this question when looking for a solution for my current problem, and realised that I have a scenario for you that extension constructors would solve. Our project is split into separate assemblies for data access, logic and UI (because some of these components are reused elsewhere). Our data access requires public parameterless constructors to instantiate the entities returned by queries, but we've deliberately made these private for encapsulation reasons. Extension constructors would allow us to define a public constructor in the data access assembly that would not exist elsewhere. – anaximander Jan 11 '14 at 15:00
  • 1
    Here's an awesome new scenario that it would enable: You have an immutable POCO class, where all fields are `readonly` and can only be set by a constructor, and you want to be able to initialize it from a different data source, involving a type that the assembly in which the POCO class is declared does not know about. – Mason Wheeler Aug 11 '15 at 20:42
  • Maybe type-specific constraints. Example: In `MyClass` it would be nice to be able to constrain `T` to just `int` and `bool` with the use of just two constructors. One taking `int` as an argument, and the other `bool`. – Tyler Pantuso Dec 23 '15 at 19:25
23

In a word - no. Take a look at this for some explanation.

They were cut from the C# 3 feature list, then they were cut from the C# 4 feature list, and we can only hope that they could make the C# 5 features, but I'm not very optimistic.

SWeko
  • 30,434
  • 10
  • 71
  • 106
13

I know this is a bump, just wanted to point out you can inherit the List class and do something like this:

class List<T> : System.Collections.Generic.List<T>
    {
        public List(T[] a, int n)
            : base()
        {
                AddRange(a, n);
        }
    }
Bauss
  • 2,767
  • 24
  • 28
0

Yes-ish but no?

MyClass{
   public MyClass(params){ //do stuff };
   public MyClass MyConstructorAddOn(moreParams){ //do more stuff; return this;}
}

then call this way:

MyClass(params).MyConstructorAddOn(moreParams); 

It works a bit like an extension method. Although NOT a constructor, it can be used as a daisy chain on a constructor to do more stuff outside of the constructor immediately. I believe this is called fluent interfaces.

Patrick Knott
  • 1,666
  • 15
  • 15