【问题标题】:Constructor selection for multiple optional parameters of the same type同一类型的多个可选参数的构造函数选择
【发布时间】:2021-01-30 13:21:47
【问题描述】:

在下面的代码中,CreateNode 调用第一个构造函数,正如 here 解释的那样(感谢链接)。

public class Node
{
    public Node(Node parent = null, params Node[] children) { }
    public Node(params Node[] children) { }
    public Node CreateNode() => new Node(new Node(), new Node()); }
}

在保留跨用途构造函数功能的同时处理此问题的最佳方法是什么(它允许代码组合更具表现力,例如 XElement)。

我在想可能暂时包装或转换parent,但这显然会引入更多样板。不确定我是否可以以某种方式利用ValueTuple<> 语法来获得我想要的东西?还是隐式和显式运算符?!

编辑

我想以与 XElement 等类似的方式创建节点,例如

new Node(new Node(new Node())

但是在某些情况下,我已经创建了一个父节点并希望将其传递给其子节点的构造函数,例如

Node parent = new Node();
new Node(parent, new Node(), new Node());

显然编译器必须选择一个,所以我想我真的在问如何强制它选择另一个,所以它知道第一个参数应该被视为父级。

【问题讨论】:

  • 所以你想改为调用第二个?
  • 是的,我希望能够使用尽可能少的语法糖来选择其中一个!这更多的是启用简洁的编码风格而不是性能等问题,我想知道如何做到最好:0)
  • 与您的问题无关,但为什么parent 参数是可选的?调用第一个重载并将null 传递给parent 与调用第二个重载不一样吗?在这两种情况下,您都在创建一个没有父节点的节点,对吧?
  • 我可能会创建一个有父节点的节点,一个有父节点和子节点的节点,或者一个只有子节点的节点。这两个构造函数涵盖了所有基础。我是一个尴尬的客户,对不起:-D
  • 我还是不明白为什么parent 必须是可选的?现在你有两种方法可以创建没有父节点的节点...new Node(new [] { new Node() })(第二个构造函数)和new Node(null, new Node())(第一个构造函数)

标签: c# .net compilation


【解决方案1】:

现在您正在以“扩展形式”传递参数数组,这会导致应用此规则,从而使两个方法都成为 applicable function member

如果包含参数数组的函数成员不适用 在其正常形式中,函数成员可以改为适用于 它的扩展形式:

  • 通过将函数成员声明中的参数数组替换为零个或多个值参数来构造扩展形式 参数数组的元素类型,使得 参数列表 A 中的参数与 参数。 [...]

然后better function member 中的规则决定第一个是更好的函数成员。具体来说,这个:

否则,如果Mp 的声明参数比Mq 多,则Mp 优于Mq。如果这两种方法都有参数数组并且仅适用于它们的扩展形式,则可能会发生这种情况。

所以要解决这个问题,只需以“正常形式”传递参数,即作为数组。如果使用隐式类型的数组,击键次数也不会多。

new Node(new[] { new Node(), new Node() })

这样,只有一个重载是适用的函数成员。

【讨论】:

  • 是的,我喜欢这个选项,就像你说的,只是多敲几下键而已!反过来能行吗?例如,将父级包装在一个数组中(请耐心等待!)而不是子级,因为这是不太常见的情况(仍在追逐最后几个击键!!)。干杯。
  • @3-14159265358979323846264 你也可以使用new Node(someParent, new[] { children1, children2 }),但是你仍然需要将子元素包裹在一个数组中。像Node.WithChildren 这样的静态方法怎么样?
  • 对不起,我很笨,两个构造函数一起作为数组意味着我总是必须声明为 new[] 所以请忽略该评论,对不起!
  • Node.WithChildren 也是一个不错的选择。非常感谢您的帮助。 GME ;0)
猜你喜欢
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2018-07-14
相关资源
最近更新 更多