例如,使用要从中派生的基类:
public abstract class BaseClass
{
protected BaseClass(int a, int b, int c)
{
}
}
要执行的非编译伪代码:
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版本(见下文,了解更严格的解决方案)
使用更新的C#特性,即out-var,您可以摆脱公共静态工厂方法。
我刚刚(偶然)发现,在base内部调用的方法的out var参数-“call”流到构造函数主体。(可能是C#的怪癖,请参阅2023版本的C#1.0兼容解决方案)
使用一个静态私有帮助器方法,它可以向外部生成所有必需的基本参数(如果需要,还可以添加其他数据),这只是一个公共的普通构造函数:
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更新
您只需要一个额外的私有构造函数和一个附带的私有静态工厂方法,该方法使用与公共构造函数相同的输入为新的私有构造函数准备数据:
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);
}
不需要特殊的C#版本,C#10记录结构只是为了简短,也可以与任何C#1.0类一起使用。
这个版本似乎稍长,但它更容易阅读和理解。