Example, using this base class you want to derive from:
public abstract class BaseClass
{
protected BaseClass(int a, int b, int c)
{
}
}
The non-compiling pseudo code you want to execute:
public class DerivedClass : BaseClass
{
private readonly object fatData;
public DerivedClass(int m)
{
var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };
base(fd.A, fd.B, fd.C); // base-constructor call
this.fatData = fd;
}
}
2020 version (see below for even more stringent solution)
Using newer C# features, namely out var
, you can get rid of the public static factory-method.
I just found out (by accident) that out var parameter of methods called inside base-"call" flow to the constructor body. (maybe it's a C# quirk, see 2023 version for C# 1.0 compatible solution)
Using a static private helper method which produces all required base arguments (plus additional data if needed) to the outside it is just a public plain constructor:
public class DerivedClass : BaseClass
{
private readonly object fatData;
public DerivedClass(int m)
: base(PrepareBaseParameters(m, out var b, out var c, out var fatData), b, c)
{
this.fatData = fatData;
Console.WriteLine(new { b, c, fatData }.ToString());
}
private static int PrepareBaseParameters(int m, out int b, out int c, out object fatData)
{
var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };
(b, c, fatData) = (fd.B, fd.C, fd); // Tuples not required but nice to use
return fd.A;
}
}
2023 update
All you need is an additional private constructor and an accompanying private static factory method which prepares the data for the new private constructor using the same input as for the public ctor:
public class DerivedClass : BaseClass
{
private readonly FatData fatData;
public DerivedClass(int m)
: this(PrepareBaseParameters(m))
{
Console.WriteLine(this.fatData.ToString());
}
private DerivedClass(FatData fd)
: base(fd.A, fd.B, fd.C)
{
this.fatData = fd;
}
private static FatData PrepareBaseParameters(int m)
{
// might be any (non-async) code which e.x. calls factory methods
var fd = new FatData(A: 1 * m, B: 2 * m, C: 3 * m);
return fd;
}
private readonly record struct FatData(int A, int B, int C);
}
No special C# version needed, the C#10 record struct just for shortness, will work with any C#1.0 class, too.
This version seems to be slightly longer but it is far easier to read and understand.