我能想到的最好的/最接近你的结果是:
_ = 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;
}
}
}
即虽然这是定义辅助方法的几行代码,但您可以在整个地方重用它作为一个衬里,而且它更具可读性,如果不是那么聪明的话。