Is there a way to use a ternary operator - or similar method - for picking the variable to assign to?
is it possible to differ the variable I'm assigning to depending on a condition? The issue I came across is wanting to do this:
(bEquipAsSecondary ? currentWeaponOffhand : currentWeaponMainhand) = weaponToSwitchTo;
Instead of
if (bEquipAsSecondary)
{
currentWeaponOffhand = weaponToSwitchTo;
}
else
{
currentWeaponMainhand = weaponToSwitchTo;
}
Which results in the following error
Error CS0131 The left-hand side of an assignment must be a variable, property or indexer
So I was wondering if there was a way to do this to cut down on space used and - in my opinion - make it look a bit neater?
c# .net ternary-operator
add a comment |
is it possible to differ the variable I'm assigning to depending on a condition? The issue I came across is wanting to do this:
(bEquipAsSecondary ? currentWeaponOffhand : currentWeaponMainhand) = weaponToSwitchTo;
Instead of
if (bEquipAsSecondary)
{
currentWeaponOffhand = weaponToSwitchTo;
}
else
{
currentWeaponMainhand = weaponToSwitchTo;
}
Which results in the following error
Error CS0131 The left-hand side of an assignment must be a variable, property or indexer
So I was wondering if there was a way to do this to cut down on space used and - in my opinion - make it look a bit neater?
c# .net ternary-operator
What are the exact types ofcurrentWeaponOffhand
andcurrentWeaponMainhand
?
– sellotape
Nov 18 '18 at 14:52
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02
add a comment |
is it possible to differ the variable I'm assigning to depending on a condition? The issue I came across is wanting to do this:
(bEquipAsSecondary ? currentWeaponOffhand : currentWeaponMainhand) = weaponToSwitchTo;
Instead of
if (bEquipAsSecondary)
{
currentWeaponOffhand = weaponToSwitchTo;
}
else
{
currentWeaponMainhand = weaponToSwitchTo;
}
Which results in the following error
Error CS0131 The left-hand side of an assignment must be a variable, property or indexer
So I was wondering if there was a way to do this to cut down on space used and - in my opinion - make it look a bit neater?
c# .net ternary-operator
is it possible to differ the variable I'm assigning to depending on a condition? The issue I came across is wanting to do this:
(bEquipAsSecondary ? currentWeaponOffhand : currentWeaponMainhand) = weaponToSwitchTo;
Instead of
if (bEquipAsSecondary)
{
currentWeaponOffhand = weaponToSwitchTo;
}
else
{
currentWeaponMainhand = weaponToSwitchTo;
}
Which results in the following error
Error CS0131 The left-hand side of an assignment must be a variable, property or indexer
So I was wondering if there was a way to do this to cut down on space used and - in my opinion - make it look a bit neater?
c# .net ternary-operator
c# .net ternary-operator
edited Nov 18 '18 at 16:46
S.Akbari
30.3k93673
30.3k93673
asked Nov 18 '18 at 14:44
JimLikesCookiesJimLikesCookies
433
433
What are the exact types ofcurrentWeaponOffhand
andcurrentWeaponMainhand
?
– sellotape
Nov 18 '18 at 14:52
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02
add a comment |
What are the exact types ofcurrentWeaponOffhand
andcurrentWeaponMainhand
?
– sellotape
Nov 18 '18 at 14:52
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02
What are the exact types of
currentWeaponOffhand
and currentWeaponMainhand
?– sellotape
Nov 18 '18 at 14:52
What are the exact types of
currentWeaponOffhand
and currentWeaponMainhand
?– sellotape
Nov 18 '18 at 14:52
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02
add a comment |
4 Answers
4
active
oldest
votes
Not sure if this is really efficient, but if you really want to stick to ternary operator, here is my 2 cents...
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
Apparently, you don't need thevar _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
add a comment |
Not sure if a ternary operator is a better choice than a regular if-else
statement here. But you can use Action
, something like this:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make anAction
for every possible state mutation, and then the game logic figures out whichAction
from its collection needs to be executed, and executes it.
– Eric Lippert
Nov 18 '18 at 15:07
add a comment |
The best / closest to what you're after that I could think of is this:
_ = condition ? (a = c) : (b = c);
In context:
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}");
Outputs
a = 3; b = 2; c = 3
Explanation
_ =
is required as the ternary operator is only available if we're assigning to something. Here we use_
as the "discard" variable; i.e. we don't care about the returned value; only that the operation itself occurs.
use of brackets (e.g.
(a = c)
is required around the assignment since we need to return a result. Performinga = c
assigns the value ofc
toa
, but doesn't return anything to the caller.(a = c)
on the other hand assignsc
toa
and then outputs the new value ofa
, making it available in the context of the rest of the method. i.e. Aisde from the assignments this statement effectively reads_ = condition ? c : c;
.
- All else is as you'd expect from the standard ternary operator. However, any questions, please say.
Thoughts
It's not ideal as you have to specify each assignment separately; but does give you a form of shorthand...
I suspect this would generally be frowned upon in a code review though, since it's less readable than the standard if/else approach...
NB: In some other languages, a trick that could be used would be to have the condition act as an index for an array (e.g. false=0, true=1) and then exploit this in assigning the value... However, whilst you can force this in C#, it's not pretty:
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();
}
}
That said, the above is talking about creating a more generic approach... If your use case is limited to weapon assignment / similar use cases, you could use a similar trick, such as this:
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{ /* ... */ }
If you find you're having to do a lot of statements like this throughout your code and want a way to keep your line count down, you're best of with something like this:
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;
}
}
}
i.e. Whilst this is several lines of code to define the helper method, you can reuse it all over the place as a one liner, and it's much more readable, if not so clever.
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used[ref]
instead ofref
and concluded it didn't work; doh!). Good luck.
– JohnLBevan
Nov 18 '18 at 16:45
add a comment |
You can use the ternary operator to choose an action that will update the right slot.
//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);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53362087%2fis-there-a-way-to-use-a-ternary-operator-or-similar-method-for-picking-the-v%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not sure if this is really efficient, but if you really want to stick to ternary operator, here is my 2 cents...
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
Apparently, you don't need thevar _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
add a comment |
Not sure if this is really efficient, but if you really want to stick to ternary operator, here is my 2 cents...
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
Apparently, you don't need thevar _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
add a comment |
Not sure if this is really efficient, but if you really want to stick to ternary operator, here is my 2 cents...
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
Not sure if this is really efficient, but if you really want to stick to ternary operator, here is my 2 cents...
(bEquipAsSecondary ? ref currentWeaponOffhand : ref currentWeaponMainhand) = weaponToSwitchTo;
edited Nov 18 '18 at 15:02
answered Nov 18 '18 at 14:56
Anu ViswanAnu Viswan
4,3682524
4,3682524
Apparently, you don't need thevar _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
add a comment |
Apparently, you don't need thevar _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
Apparently, you don't need the
var _ =
– haim770
Nov 18 '18 at 15:00
Apparently, you don't need the
var _ =
– haim770
Nov 18 '18 at 15:00
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
@haim770 thanks for pointing it out :)
– Anu Viswan
Nov 18 '18 at 15:02
1
1
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
Nice one! Although would need to wait for unity to include C#7.2 to be able to use byref locals/returns
– JimLikesCookies
Nov 18 '18 at 15:03
add a comment |
Not sure if a ternary operator is a better choice than a regular if-else
statement here. But you can use Action
, something like this:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make anAction
for every possible state mutation, and then the game logic figures out whichAction
from its collection needs to be executed, and executes it.
– Eric Lippert
Nov 18 '18 at 15:07
add a comment |
Not sure if a ternary operator is a better choice than a regular if-else
statement here. But you can use Action
, something like this:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make anAction
for every possible state mutation, and then the game logic figures out whichAction
from its collection needs to be executed, and executes it.
– Eric Lippert
Nov 18 '18 at 15:07
add a comment |
Not sure if a ternary operator is a better choice than a regular if-else
statement here. But you can use Action
, something like this:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
Not sure if a ternary operator is a better choice than a regular if-else
statement here. But you can use Action
, something like this:
(bEquipAsSecondary ? new Action(() => currentWeaponOffhand = weaponToSwitchTo)
: () => currentWeaponMainhand = weaponToSwitchTo)();
edited Nov 19 '18 at 7:39
answered Nov 18 '18 at 14:49
S.AkbariS.Akbari
30.3k93673
30.3k93673
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make anAction
for every possible state mutation, and then the game logic figures out whichAction
from its collection needs to be executed, and executes it.
– Eric Lippert
Nov 18 '18 at 15:07
add a comment |
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make anAction
for every possible state mutation, and then the game logic figures out whichAction
from its collection needs to be executed, and executes it.
– Eric Lippert
Nov 18 '18 at 15:07
3
3
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make an
Action
for every possible state mutation, and then the game logic figures out which Action
from its collection needs to be executed, and executes it.– Eric Lippert
Nov 18 '18 at 15:07
I like this solution because it then generalizes into a framework for handling the effects of all game actions: you make an
Action
for every possible state mutation, and then the game logic figures out which Action
from its collection needs to be executed, and executes it.– Eric Lippert
Nov 18 '18 at 15:07
add a comment |
The best / closest to what you're after that I could think of is this:
_ = condition ? (a = c) : (b = c);
In context:
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}");
Outputs
a = 3; b = 2; c = 3
Explanation
_ =
is required as the ternary operator is only available if we're assigning to something. Here we use_
as the "discard" variable; i.e. we don't care about the returned value; only that the operation itself occurs.
use of brackets (e.g.
(a = c)
is required around the assignment since we need to return a result. Performinga = c
assigns the value ofc
toa
, but doesn't return anything to the caller.(a = c)
on the other hand assignsc
toa
and then outputs the new value ofa
, making it available in the context of the rest of the method. i.e. Aisde from the assignments this statement effectively reads_ = condition ? c : c;
.
- All else is as you'd expect from the standard ternary operator. However, any questions, please say.
Thoughts
It's not ideal as you have to specify each assignment separately; but does give you a form of shorthand...
I suspect this would generally be frowned upon in a code review though, since it's less readable than the standard if/else approach...
NB: In some other languages, a trick that could be used would be to have the condition act as an index for an array (e.g. false=0, true=1) and then exploit this in assigning the value... However, whilst you can force this in C#, it's not pretty:
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();
}
}
That said, the above is talking about creating a more generic approach... If your use case is limited to weapon assignment / similar use cases, you could use a similar trick, such as this:
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{ /* ... */ }
If you find you're having to do a lot of statements like this throughout your code and want a way to keep your line count down, you're best of with something like this:
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;
}
}
}
i.e. Whilst this is several lines of code to define the helper method, you can reuse it all over the place as a one liner, and it's much more readable, if not so clever.
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used[ref]
instead ofref
and concluded it didn't work; doh!). Good luck.
– JohnLBevan
Nov 18 '18 at 16:45
add a comment |
The best / closest to what you're after that I could think of is this:
_ = condition ? (a = c) : (b = c);
In context:
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}");
Outputs
a = 3; b = 2; c = 3
Explanation
_ =
is required as the ternary operator is only available if we're assigning to something. Here we use_
as the "discard" variable; i.e. we don't care about the returned value; only that the operation itself occurs.
use of brackets (e.g.
(a = c)
is required around the assignment since we need to return a result. Performinga = c
assigns the value ofc
toa
, but doesn't return anything to the caller.(a = c)
on the other hand assignsc
toa
and then outputs the new value ofa
, making it available in the context of the rest of the method. i.e. Aisde from the assignments this statement effectively reads_ = condition ? c : c;
.
- All else is as you'd expect from the standard ternary operator. However, any questions, please say.
Thoughts
It's not ideal as you have to specify each assignment separately; but does give you a form of shorthand...
I suspect this would generally be frowned upon in a code review though, since it's less readable than the standard if/else approach...
NB: In some other languages, a trick that could be used would be to have the condition act as an index for an array (e.g. false=0, true=1) and then exploit this in assigning the value... However, whilst you can force this in C#, it's not pretty:
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();
}
}
That said, the above is talking about creating a more generic approach... If your use case is limited to weapon assignment / similar use cases, you could use a similar trick, such as this:
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{ /* ... */ }
If you find you're having to do a lot of statements like this throughout your code and want a way to keep your line count down, you're best of with something like this:
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;
}
}
}
i.e. Whilst this is several lines of code to define the helper method, you can reuse it all over the place as a one liner, and it's much more readable, if not so clever.
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used[ref]
instead ofref
and concluded it didn't work; doh!). Good luck.
– JohnLBevan
Nov 18 '18 at 16:45
add a comment |
The best / closest to what you're after that I could think of is this:
_ = condition ? (a = c) : (b = c);
In context:
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}");
Outputs
a = 3; b = 2; c = 3
Explanation
_ =
is required as the ternary operator is only available if we're assigning to something. Here we use_
as the "discard" variable; i.e. we don't care about the returned value; only that the operation itself occurs.
use of brackets (e.g.
(a = c)
is required around the assignment since we need to return a result. Performinga = c
assigns the value ofc
toa
, but doesn't return anything to the caller.(a = c)
on the other hand assignsc
toa
and then outputs the new value ofa
, making it available in the context of the rest of the method. i.e. Aisde from the assignments this statement effectively reads_ = condition ? c : c;
.
- All else is as you'd expect from the standard ternary operator. However, any questions, please say.
Thoughts
It's not ideal as you have to specify each assignment separately; but does give you a form of shorthand...
I suspect this would generally be frowned upon in a code review though, since it's less readable than the standard if/else approach...
NB: In some other languages, a trick that could be used would be to have the condition act as an index for an array (e.g. false=0, true=1) and then exploit this in assigning the value... However, whilst you can force this in C#, it's not pretty:
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();
}
}
That said, the above is talking about creating a more generic approach... If your use case is limited to weapon assignment / similar use cases, you could use a similar trick, such as this:
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{ /* ... */ }
If you find you're having to do a lot of statements like this throughout your code and want a way to keep your line count down, you're best of with something like this:
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;
}
}
}
i.e. Whilst this is several lines of code to define the helper method, you can reuse it all over the place as a one liner, and it's much more readable, if not so clever.
The best / closest to what you're after that I could think of is this:
_ = condition ? (a = c) : (b = c);
In context:
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}");
Outputs
a = 3; b = 2; c = 3
Explanation
_ =
is required as the ternary operator is only available if we're assigning to something. Here we use_
as the "discard" variable; i.e. we don't care about the returned value; only that the operation itself occurs.
use of brackets (e.g.
(a = c)
is required around the assignment since we need to return a result. Performinga = c
assigns the value ofc
toa
, but doesn't return anything to the caller.(a = c)
on the other hand assignsc
toa
and then outputs the new value ofa
, making it available in the context of the rest of the method. i.e. Aisde from the assignments this statement effectively reads_ = condition ? c : c;
.
- All else is as you'd expect from the standard ternary operator. However, any questions, please say.
Thoughts
It's not ideal as you have to specify each assignment separately; but does give you a form of shorthand...
I suspect this would generally be frowned upon in a code review though, since it's less readable than the standard if/else approach...
NB: In some other languages, a trick that could be used would be to have the condition act as an index for an array (e.g. false=0, true=1) and then exploit this in assigning the value... However, whilst you can force this in C#, it's not pretty:
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();
}
}
That said, the above is talking about creating a more generic approach... If your use case is limited to weapon assignment / similar use cases, you could use a similar trick, such as this:
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{ /* ... */ }
If you find you're having to do a lot of statements like this throughout your code and want a way to keep your line count down, you're best of with something like this:
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;
}
}
}
i.e. Whilst this is several lines of code to define the helper method, you can reuse it all over the place as a one liner, and it's much more readable, if not so clever.
edited Nov 18 '18 at 15:57
answered Nov 18 '18 at 15:01
JohnLBevanJohnLBevan
14.4k146107
14.4k146107
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used[ref]
instead ofref
and concluded it didn't work; doh!). Good luck.
– JohnLBevan
Nov 18 '18 at 16:45
add a comment |
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used[ref]
instead ofref
and concluded it didn't work; doh!). Good luck.
– JohnLBevan
Nov 18 '18 at 16:45
1
1
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
Thanks for the thorough answer !
– JimLikesCookies
Nov 18 '18 at 16:25
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used
[ref]
instead of ref
and concluded it didn't work; doh!). Good luck.– JohnLBevan
Nov 18 '18 at 16:45
No worries / good luck. Obviously Anu's solution's better for the pure ternary approach (I'd tried that but was in PS mode so used
[ref]
instead of ref
and concluded it didn't work; doh!). Good luck.– JohnLBevan
Nov 18 '18 at 16:45
add a comment |
You can use the ternary operator to choose an action that will update the right slot.
//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);
add a comment |
You can use the ternary operator to choose an action that will update the right slot.
//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);
add a comment |
You can use the ternary operator to choose an action that will update the right slot.
//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);
You can use the ternary operator to choose an action that will update the right slot.
//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);
answered Nov 19 '18 at 7:56
John WuJohn Wu
30k42752
30k42752
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53362087%2fis-there-a-way-to-use-a-ternary-operator-or-similar-method-for-picking-the-v%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What are the exact types of
currentWeaponOffhand
andcurrentWeaponMainhand
?– sellotape
Nov 18 '18 at 14:52
These would be classes
– JimLikesCookies
Nov 18 '18 at 15:02