【问题标题】:Ternary conditional operator for the left-hand operand in C#C#中左侧操作数的三元条件运算符
【发布时间】:2020-08-16 14:05:38
【问题描述】:

是否可以在不使用 if 语句的情况下根据某些内联条件选择目标变量?

(!RTL ? padLeft : padRight) = NearBorder.LineWidth;

【问题讨论】:

  • 这句话的意思是什么? padLeft 和 padRight 是变量吗?如果您的意思是“根据RTL 的布尔状态,将padLeft 或padRight 变量之一设置为值NearBorder.LineWidth”,那么不,据我所知, C# 不允许这样做。您的问题确实需要显示padLeft 和padRight 的声明以及RTL 的类型
  • 欢迎来到 StackOverFlow,@AndreyDryazgov! 请您详细说明一下?我不确定我是否听懂了你的问题。
  • 在该示例中,RTL 是 bool 类型的属性; padLeft、padRight 和 NearBorder.LineWidth 是浮点类型。我只是在寻找一种避免重复右侧操作数而不为临时结果创建新变量的方法。
  • 在下面查看我的答案。如果您使用的是最新的编译器,它应该可以满足您的需求

标签: c# variable-assignment conditional-operator


【解决方案1】:

如果您使用的是新版本的 C# (7.2+),并且这些变量是本地变量或字段,那么您可以使用 ref locals;

(!RTL ? ref padLeft : ref padRight) = NearBorder.LineWidth;

有关示例,请参阅此 sharplab 链接。请注意,proposal docs(将其称为conditional ref)表明这仍然是一个提案。 Championed GitHub 问题仍然开放,但似乎表明唯一缺少的是真正的规范。这个comment on that issue 表明它都是作为更大的ref readonly 主题的一部分实现的。

除此之外,这段代码在 SharpLab 和 VS2019 本地都适用于我(最新,非预览版,使用 dotnet core 3.0)

如果这些变量是字段,您可以也使用ref return 并将逻辑封装到一个函数中。例如:

// class fields
int padLeft, padRight;  
// ref returning method 
private ref int GetPad() => ref (!RTL ? ref padLeft : ref padRight);
// actually use it
void SetPad() {
    // assignment to a method! 
    GetPad() = NearBorder.LineWidth;
} 

有关ref locals 和ref returns(最初是C# 7 的一部分)概念的更多信息,请参阅这篇MSDN 文章。

【讨论】:

  • 非常酷!我刚刚尝试过以下代码: (GetBool() ? ref x : ref y) += 5;它对我有用。非常感谢!
【解决方案2】:

好吧,如果您使用三元运算符来选择一个委托并让委托进行分配,这是有可能的。它怀疑你会在实际使用中看到这种技术。 if 声明是执行此操作的常用方法。

    var a = new Action<int>( i => padLeft = i );
    var b = new Action<int>( i => padRight = i );

    (!RTL ? a : b)(NearBorder.LineWidth);

【讨论】:

  • 是的,但我希望有一种更适合生产的方式来做同样的事情。从编译器的角度来看,在对目标变量做出决定之前,必须很容易将右手表达式的结果保存在某个地方。
【解决方案3】:

让我们试试看会发生什么:

var a =1; var b =1; var c=1;
(a == 1? b : c) = 4

如果你运行它,你会得到

赋值的左边必须是变量、属性或 索引器 这指的是 = 符号剩下的所有内容。

但是,您可以有条件地分配给一个变量或另一个,但您必须使用分配变量两次。这会像你期望的那样工作:

!RTL ? padLeft = NearBorder.LineWidth : padRight = NearBorder.LineWidth;

但是在您的具体情况下,我可能会使用不同的代码。

padLeft = RTL ? NearBorder.LineWidth: 0;
padRight = !RTL ? NearBorder.LineWidth: 0;

【讨论】:

  • 您的不同版本有不同的结果——他的代码不会将未使用的变量归零。
猜你喜欢
  • 2017-07-16
  • 2012-04-02
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-13
  • 2015-02-15
  • 2022-12-06
相关资源
最近更新 更多