(一)可空类型到底有什么意义
不好的代码:
正常返回NodeType,但是异常返回什么呢?这是个问题,所以作者想返回异常的方式。
这样会影响性能,异常不要用于转变程序流程。
public enum NodeType { Start, Process, Decision, Loop, End } private NodeType GetNodeTypeInMousePos(int mouseX,int mouseY) { // 获取滚动条偏移量 int scrollX = -panel1.AutoScrollPosition.X; int scrollY = -panel1.AutoScrollPosition.Y; // 调整鼠标位置,考虑滚动条偏移 Point adjustedLocation = new Point(mouseX + scrollX, mouseY + scrollY); // 遍历所有节点,查找点击位置的节点 for (int x = 0; x < GridWidth; x++) { for (int y = 0; y < GridHeight; y++) { var node = nodes[x, y]; if (node != null && node.Bounds != null && node.Bounds.Contains(adjustedLocation)) { return node.Type; } } } throw new ArgumentNullException("未知节点类型"); }
正确的代码:
使用了可空类型。这样你就可以返回一个空值,在调用者那里进行判断了。
private NodeType? GetNodeTypeInMousePos(int mouseX, int mouseY) { // 获取滚动条偏移量 int scrollX = -panel1.AutoScrollPosition.X; int scrollY = -panel1.AutoScrollPosition.Y; // 调整鼠标位置,考虑滚动条偏移 Point adjustedLocation = new Point(mouseX + scrollX, mouseY + scrollY); // 遍历所有节点,查找点击位置的节点 for (int x = 0; x < GridWidth; x++) { for (int y = 0; y < GridHeight; y++) { var node = nodes[x, y]; if (node != null && node.Bounds != null && node.Bounds.Contains(adjustedLocation)) { return node.Type; } } } return null; // 未找到节点时返回null }
(二)对象初始化器的问题
当执行完下面代码时,我在logUnit的构造函里检查LogType,它还是为null。
new logUnit
{
Dock = DockStyle.Fill,
LogType = logTypes[i]
};
但当执行到下面语句时,这个时候就在logUnit里下断点发现LogType有值了。
newUnit.UpdateTitle(); // 立即更新标题
这是什么原因,不懂,难道不是logUnit的构造函数里LogType就立刻有值了吗?
这是因为在C#中,对象初始化器( { Dock = DockStyle.Fill, LogType = logTypes[i] } )
是在构造函数执行 之后 才执行的。具体顺序如下:
1. 首先调用 logUnit 的构造函数
2. 构造函数执行完成后,对象初始化器才开始执行,为属性赋值
3. 最后执行 UpdateTitle() 方法

