C# 可选参数 / 多个必需参数

3

是否有可能一次性获得两个可选的参数需求?以下是一个示例:

public void ParamChoise(string A, bool B = false, string C = "Y")
    {
        // Stuff here
    }

如果B是可选的,当B为真时,我希望函数需要C。根据我的逻辑,大致如下:

public void ParamChoise(string A, (bool B = false, string C = "Y"))

在谷歌搜索中没有发现任何相关内容。我可以尝试的一个方法是:

        /// <summary>
        /// If you want behaviour XXX to be enabled, please enter "C" for usage.
        /// </summary>
        /// <param name="A"></param>
        /// <param name="C"></param>
        public void ParamChoise(string A, string C = "Y")
        {
            // Stuff here
        }

当然,我可以给我的函数添加这样的注释,但是为一个不合逻辑的参数编写注释让我感到很糟糕。
这个例子可能不太好,但我肯定将来会再次遇到这种情况。
非常感谢:)。
编辑以澄清事情:
参数的可能组合:
- 仅 A - A 和 (B & C) - NOT A & B - NOT A & C(因为如果需要C,B会得到点数)

3
不可以在方法头中进行参数检查,但是可以引入两个重载方法来实现。无论如何,如果其中一个参数缺失而另一个参数已提供,也可以抛出异常。 - MakePeaceGreatAgain
但是在调用“ParamChoice”之前,您始终可以确定是否需要“C”。 - Amit Kumar Ghosh
从可读性角度来看,这样做会非常糟糕。只需使用明确的方法和独特的名称,将逻辑传递给调用者。 - Meirion Hughes
无论如何,您都必须问自己是否最好为“B=true”和“B=false”拥有两个不同的函数;当然,它们可以调用相同的私有函数来执行实际工作。 - J Fabian Meier
NOT A & B - 这是指布尔运算符 ! 中的 NOT,还是像“我不想要”一样的含义? - Jamiec
显示剩余2条评论
3个回答

6
我认为您需要使用旧的方法 - 方法重载。
// b = true
public void ParamChoise(string A, string C)

// b = false
public void ParamChoise(string A)

他们应该调用您原始版本的私有版本。
private void ParamChoiseInternal(string A, bool B = false, string C = "")

您需要确保给这两个公有方法命名的精准表达它们的含义 - 这将有助于程序员(可能是您自己)在当前状态下调用正确的方法。


更新后

与上述相同,名称反映要求,并且您仍应能够调用原始的私有方法。重载确保了您的一致性。

public void AOnly(string A)
public void AAndBAndC(string A, bool B, string C)

很难理解这两个条件:

没有 C 的情况下不包括 A 和 B !!!
不包括 A 和 C (因为如果需要 C,则 B 会得到该点)


1
而且,如果B描述了一些重要的属性,这可以在两种不同的方法的名称中体现出来。 - J Fabian Meier
他想让B变成可选项,直到C被给出。这在没有逻辑的情况下是不可能的。 - Meirion Hughes
好的,但是这个答案在第二种情况下完全忽略了C(b = false)...它仍然需要存在,只是当b = true时是可选的。 - Meirion Hughes
如果第一个函数是 (string A, bool B, string C),那不就是解决方案了吗?如果给定B,它将需要C...!? - C4d
是的,就是这样。对于你最后一个问题,我可以使用相同的名称吗?我的意思是我可以将两个函数都称为“myFunc”吗? - C4d
显示剩余3条评论

1
你可以使用命名参数
public void ParamChoise(string A = "", bool B = false, string C = "Y") {...}

// call it
ParamChoise(A: "123");
ParamChoise(C: "123");
ParamChoise(C: "123", A: "123");
ParamChoise(B: true, C: "123", A: "123");

我发现这对于具有许多可选参数的方法非常有用。
通过显式参数名称指定,您可以自由地在任何位置添加新的可选参数,而不会破坏现有代码。

但这并没有解决我的问题。你的第二个和第三个调用不应该是可能的。请检查我在问题上的编辑。 - C4d
1
然后,您必须使用覆盖(仅公开有效组合)并将其称为“ParamChoise”(接受任何内容),只需使其非“public”。 - Sinatr

1
据我了解,您希望在b为false时将C设置为可选项;作为方法重载的练习,我认为最接近的方法是:
void ParamChoise(string A, string C)
void ParamChoise(string A, bool B = true, string C = "Y")

您仍需在调用方决定是否提供Bool...这使得它变得毫无意义,因为现在您可以这样做:

void ParamChoiseBIsFalse(string A, string C)
void ParamChoiseBIsTrue(string A, string C = "Y")

你刚刚得到了无法直接转换为简单重载的复杂逻辑。你需要将该逻辑放在被调用者或调用者中。


是的,在布尔类型的情况下,这是无意义的。但总的来说,我会将你的答案保留到未来,以防我遇到另一个需要这些条件的问题。因此,第一个没有可选 C 的示例是正确的。无论如何,我已经选择了@Jamiec的答案,因为他更快。 - C4d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接