Is there a way to use a ternary operator - or similar method - for picking the variable to assign to?












8















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?










share|improve this question

























  • 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
















8















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?










share|improve this question

























  • 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














8












8








8








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 of currentWeaponOffhand and currentWeaponMainhand?

    – 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











  • 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












4 Answers
4






active

oldest

votes


















7














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;





share|improve this answer


























  • 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






  • 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



















3














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)();





share|improve this answer





















  • 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



















0














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. Performing a = c assigns the value of c to a, but doesn't return anything to the caller. (a = c) on the other hand assigns c to a and then outputs the new value of a, 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.






share|improve this answer





















  • 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 of ref and concluded it didn't work; doh!). Good luck.

    – JohnLBevan
    Nov 18 '18 at 16:45



















0














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);





share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    7














    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;





    share|improve this answer


























    • 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






    • 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
















    7














    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;





    share|improve this answer


























    • 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






    • 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














    7












    7








    7







    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;





    share|improve this answer















    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;






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 the var _ =

      – 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











    • @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













    3














    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)();





    share|improve this answer





















    • 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
















    3














    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)();





    share|improve this answer





















    • 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














    3












    3








    3







    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)();





    share|improve this answer















    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)();






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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














    • 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








    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











    0














    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. Performing a = c assigns the value of c to a, but doesn't return anything to the caller. (a = c) on the other hand assigns c to a and then outputs the new value of a, 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.






    share|improve this answer





















    • 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 of ref and concluded it didn't work; doh!). Good luck.

      – JohnLBevan
      Nov 18 '18 at 16:45
















    0














    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. Performing a = c assigns the value of c to a, but doesn't return anything to the caller. (a = c) on the other hand assigns c to a and then outputs the new value of a, 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.






    share|improve this answer





















    • 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 of ref and concluded it didn't work; doh!). Good luck.

      – JohnLBevan
      Nov 18 '18 at 16:45














    0












    0








    0







    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. Performing a = c assigns the value of c to a, but doesn't return anything to the caller. (a = c) on the other hand assigns c to a and then outputs the new value of a, 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.






    share|improve this answer















    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. Performing a = c assigns the value of c to a, but doesn't return anything to the caller. (a = c) on the other hand assigns c to a and then outputs the new value of a, 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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 of ref and concluded it didn't work; doh!). Good luck.

      – JohnLBevan
      Nov 18 '18 at 16:45














    • 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 of ref 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











    0














    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);





    share|improve this answer




























      0














      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);





      share|improve this answer


























        0












        0








        0







        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);





        share|improve this answer













        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);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 '18 at 7:56









        John WuJohn Wu

        30k42752




        30k42752






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)