为什么 C# 12 主构造函数以相反的顺序执行?

问题描述 投票:0回答:1

为什么 C# 12 中的主构造函数以相反的顺序执行?

至少可以说,这是一个“突破性的改变”...... 示例:

namespace Whatever; [TestClass] public class UnitTestTemp { [TestMethod] public void TestMethod1() // PASS // is expected, 1st is 1, 2nd is 2 { using var stream = new MemoryStream(new byte[] { 1, 2, 3, 4 }); var classicDerived = new ClassicDerived(stream); Console.WriteLine(classicDerived.Value1); Console.WriteLine(classicDerived.Value2); Assert.AreEqual(1, classicDerived.Value1); Assert.AreEqual(2, classicDerived.Value2); } [TestMethod] public void TestMethod2() // FAIL // is opposite, 1st is 2, 2nd is 1 { using var stream = new MemoryStream(new byte[] { 1, 2, 3, 4 }); var primaryDerived = new PrimaryDerived(stream); Console.WriteLine(primaryDerived.Value1); Console.WriteLine(primaryDerived.Value2); Assert.AreEqual(1, primaryDerived.Value1); Assert.AreEqual(2, primaryDerived.Value2); } }

经典构造函数:

public class ClassicBase { public readonly int Value1; protected ClassicBase(Stream stream) { Value1 = stream.ReadByte(); } } public class ClassicDerived : ClassicBase { public readonly int Value2; public ClassicDerived(Stream stream) : base(stream) { Value2 = stream.ReadByte(); } }

主构造函数:

public class PrimaryBase(Stream stream) { public readonly int Value1 = stream.ReadByte(); } public class PrimaryDerived(Stream stream) : PrimaryBase(stream) { public readonly int Value2 = stream.ReadByte(); }

第一次测试结果:

 TestMethod1  Source: UnitTestTemp.cs line 7  Duration: 4 ms Standard Output:  1 2

第二次测试结果:

 TestMethod2  Source: UnitTestTemp.cs line 21  Duration: 26 ms Message:  Assert.AreEqual failed. Expected:<1>. Actual:<2>. Stack Trace:  UnitTestTemp.TestMethod2() line 30 RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr) Standard Output:  2 1

如您所见,如果您在构造函数中使用流,就会有点问题。

问题:

除了恢复到经典构造函数之外,还有其他方法可以解决这个问题吗?

(正在考虑类似

SetsRequiredMembers

的新 required 修饰符)

c# constructor c#-12.0
1个回答
0
投票

在 Classic 类中,您在构造函数中进行初始化,而在 Primary 类中,您在初始值设定项中进行初始化。而且构造函数和初始化器的执行顺序确实是不同的。这与主构造函数无关。

如果您使用初始值设定项而不涉及主构造函数,则会得到相反的顺序。

我的设置截然不同。这是我的助手类:

static class Values { private static int n = 0; public static int GetNext(string name) { n++; Console.WriteLine($"{name}: {n}"); return n; } }

经典的类层次结构:

public class ClassicBase { public readonly int Value1 = Values.GetNext(nameof(Value1)); } public class ClassicDerived : ClassicBase { public readonly int Value2 = Values.GetNext(nameof(Value2)); }

测试

var obj = new ClassicDerived(); Console.ReadKey();

打印:

Value2: 1 Value1: 2

© www.soinside.com 2019 - 2024. All rights reserved.