有没有办法使用三元运算符 - 或类似的方法 - 来选择要分配的变量?
Posted
技术标签:
【中文标题】有没有办法使用三元运算符 - 或类似的方法 - 来选择要分配的变量?【英文标题】:Is there a way to use a ternary operator - or similar method - for picking the variable to assign to? 【发布时间】:2019-04-21 01:44:12 【问题描述】:是否可以根据条件改变我分配给的变量?我遇到的问题是想要这样做:
(bEquipAsSecondary ? currentWeaponOffhand : currentWeaponMainhand) = weaponToSwitchTo;
代替
if (bEquipAsSecondary)
currentWeaponOffhand = weaponToSwitchTo;
else
currentWeaponMainhand = weaponToSwitchTo;
这会导致以下错误
错误 CS0131 赋值的左侧必须是变量、属性或索引器
所以我想知道是否有办法做到这一点来减少使用的空间 - 在我看来 - 让它看起来更整洁一点?
【问题讨论】:
currentWeaponOffhand
和 currentWeaponMainhand
的具体类型是什么?
这些是类
【参考方案1】:
要使用三元运算符来选择要为其赋值的变量,您可以使用ref locals/returns。例如,
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
示例输出和代码
var currentWeaponOffhand = 4;
var currentWeaponMainhand = 5;
var weaponToSwitchTo = 7;
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
Console.WriteLine($"When bEquipAsSecondary=bEquipAsSecondary,currentWeaponOffhand=currentWeaponOffhand,currentWeaponMainhand=currentWeaponMainhand");
输出
When bEquipAsSecondary=False,currentWeaponOffhand=4,currentWeaponMainhand=7
When bEquipAsSecondary=True,currentWeaponOffhand=7,currentWeaponMainhand=5
【讨论】:
显然,您不需要var _ =
不错的一个!虽然需要等待统一包含 C#7.2 才能使用 byref locals/returns【参考方案2】:
不确定三元运算符是否比此处的常规 if-else
语句更好。但是你可以使用Action
,像这样:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
【讨论】:
我喜欢这个解决方案,因为它可以概括为一个框架来处理所有游戏动作的效果:你为每个可能的状态突变创建一个Action
,然后游戏逻辑会计算出哪个@987654326 @ 从它的集合中需要被执行,并执行它。【参考方案3】:
我能想到的最好的/最接近你的结果是:
_ = condition ? (a = c) : (b = c);
在上下文中:
bool condition = true;
int a = 1;
int b = 2;
int c = 3;
_ = condition ? (a = c) : (b = c);
Console.WriteLine($"a = a; b = b; c = c");
输出
a = 3; b = 2; c = 3
说明
_ =
是必需的,因为三元运算符仅在我们分配给某些东西时才可用。这里我们使用_
作为“丢弃”变量;即我们不关心返回值;只是操作本身发生。
使用括号(例如(a = c)
需要在赋值周围,因为我们需要返回结果。执行a = c
会将c
的值分配给a
,但不会向调用者返回任何内容。另一方面,(a = c)
将c
分配给a
,然后输出a
的新值,使其在方法的其余部分的上下文中可用。即,该语句有效地从分配中读取@987654334 @。
想法
这并不理想,因为您必须单独指定每个分配;但确实给了你一种速记形式......
我怀疑这在代码审查中通常会被拒绝,因为它的可读性不如标准 if/else 方法...
注意:在其他一些语言中,可以使用的技巧是让条件充当数组的索引(例如 false=0,true=1),然后在分配值时利用它...但是,虽然您可以在 C# 中强制执行此操作,但它并不漂亮:
void Main()
bool condition = true;
var a = new ReferenceType<int>(1);
var b = new ReferenceType<int>(2);
var c = new ReferenceType<int>(3);
(new []b, a)[ConvertBoolToInt(condition)].Value = c.Value;
Console.WriteLine($"a = a; b = b; c = c");
//in C# bools aren't natively convertable to int as they are in many langauges, so we'd need to provide a conversion method
public int ConvertBoolToInt(bool value)
return value ? 1 : 0;
//to allow us to change the value rather than only the refenence, we'd need to wrap our data in something and update the value assigned to its property
public class ReferenceType<T>
public T Value get;set;
public ReferenceType(T intValue)
Value = intValue;
public override string ToString()
return Value.ToString();
也就是说,上面讨论的是创建一种更通用的方法...如果您的用例仅限于武器分配/类似用例,您可以使用类似的技巧,例如:
public enum WeaponHandEnum
Primary //int = 0
,
Secondary //int = 1
public class Player
public Weapon[] Weapons get;set;
public Player(Weapon primary = null, Weapon secondary = null)
Weapons = new Weapon[2] primary, secondary;
public void Equip(WeaponHandEnum whichHand, Weapon newWeapon)
Weapons[(int)whichHand] = newWeapon;
public class Weapon /* ... */
如果您发现必须在整个代码中执行大量这样的语句,并且想要一种方法来减少行数,那么您最好使用以下方法:
void Main()
bool condition = true;
var a = 1;
var b = 2;
var c = 3;
SomeKindaHelper.TernaryAssign<int>(condition, ref a, ref b, c);
Console.WriteLine($"a = a; b = b; c = c");
public static class SomeKindaHelper
public static void TernaryAssign<T>(bool condition, ref T assignToMeIfConditionIsTrue, ref T assignToMeIfConditionIsFalse, T newValue)
if (condition)
assignToMeIfConditionIsTrue = newValue;
else
assignToMeIfConditionIsFalse = newValue;
即虽然这是定义辅助方法的几行代码,但您可以在整个地方重用它作为一个衬里,而且它更具可读性,如果不是那么聪明的话。
【讨论】:
感谢您的详尽回答! 别担心/祝你好运。显然,Anu 的解决方案更适合纯三元方法(我尝试过但处于 PS 模式,所以使用[ref]
而不是 ref
并得出结论它不起作用;doh!)。祝你好运。【参考方案4】:
您可以使用三元运算符来选择一个动作来更新正确的槽。
//Define action to equip appropriate slot
var equipAction = bEquipAsSecondary
? new Action<Weapon>( w => currentWeaponOffhand = w )
: new Action<Weapon>( w => currentWeaponMainhand = w );
//Now equip the weapon
equipAction(weaponToSwitchTo);
【讨论】:
以上是关于有没有办法使用三元运算符 - 或类似的方法 - 来选择要分配的变量?的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用 pine 脚本的三元运算符来指定 plotshape() 中的 style 参数或 plotchar() 中的 char 参数吗?