DEV Community

DEV Community

Matheus Gomes 👨‍💻

Posted on Jan 5, 2020

Coalescing operator and Compound assignment operator in C#

Hello! Today i want to ask you this: Have you ever used a Null Coalescing operator or even a Compound assignment operator in C# ?

Until today i had never heard about this things, so i want to share with you what i learned about and how it can be applied to your code.

The problem

Let's say you want to give a given variable the value of null.

Now, if we want to print the value on the screen it will accuse the following error:

Let's see how to get around this...

The old way 👎

The old and 'commom way' to check this is using if else operators like this:

We see that in this case we cannot place a default value to x and y operators. So we display on screen when it is null.

The Null Coalescing operator way 👌

First, a null coalescing operator (??) is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null, otherwise, it returns the right operand.

So it's mainly used to simplify checking for null values and also assign a default value to a variable when the value is null.

Using our example:

This way i can make a default value on x and y when one of them is null. And so, we can print on screen!

But can it be better?

The Compound assignment operator way 😎

The Compound assignment operator (??=) was introduced on C# 8.0 and has made our job easier. It simply reduces what we have to write and has the same result.

Instead of writing double x = x ?? 0.0; We can just write double x ??= 0.0;

Simple, right?

Hope you enjoyed this post, it's simple but it's something worth sharing for me.

Thanks for your time!😊

Links: https://dzone.com/articles/nullable-types-and-null-coalescing-operator-in-c

https://dev.to/mpetrinidev/the-null-coalescing-operator-in-c-8-0-4ib4

https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/operators/null-coalescing-operator

Top comments (3)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

wakeupmh profile image

  • Email [email protected]
  • Location São José dos Campos
  • Work Cloud Engineer | AWS Community Builder
  • Joined May 21, 2019

saint4eva profile image

  • Joined Dec 16, 2017

Good article. Thank you.

arthurbarbero profile image

  • Location Brazil
  • Work Intern at Agrotools
  • Joined Oct 22, 2019

Awesome Dude, simple but unknown by most programmers

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

kingkunte_ profile image

AI-Powered, No-code Automated Software Testing: What differentiates MagicPod from its peers?

kingkunte_ - May 15

boblied profile image

PWC 269 Two of Us Distributing Elements

Bob Lied - May 15

nikuwadaskar profile image

Mastering Higher-Order Components in React: A Guide to DRY Code

nikuwadaskar - May 15

brightdevs profile image

Spring Tests with TestContainers

bright inventions - May 15

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Bite Sized Tech is a participant in Unity Affiliate Program , Liquid Web Affiliate Program , Hostinger Affiliate Program , Namecheap Affiliate Program , Envato Elements Affiliate Program , Adobe Affiliate Program and SteelSeries Affiliate Program under which we might earn commission when visitors use our Affiliate Links and makes qualifying purchases.

Assignment Operators | Unity C# Game Development Tutorial | How To Make A Game

In C# and all the other programming languages, there are special symbols and combination of symbols which which we use to Assign values to variables .

These symbols and combination of symbols are what we call Assignment Operators in programming.

In an article before, we have already talked about Arithmetic Operators .

In this article, we are going to cover Assignment Operators and then in subsequent articles we will cover the Comparison Operators and Logical Operators .

This Post is Part of : How To Make A Game Series where i’ll be showing you how to become a game developer and will be going over the basics of Game Development, Step by Step, using the Unity Game Engine and C# Scripting Language to script the Game Logic. If you are new to Game Development or Programming in general you should definitely go through this Unity Tutorials article series as it will set give you a kick-start towards becoming an exceptional Unity 2D or 3D Video Game Developer.

If you are interested in Game Development then you might also be interested in this article on Understanding The Target Player Base Of Your Game

in which i have listed down some question that will help you better determine what your Player Base wants

and will help you make better Game Design, Game Development and Sales Decisions.

Assignment Operators - Unity C# Game Development Tutorial - How To Make A Game - Featured Image

Related Articles On Operators in C#

  • Arithmetic Operators in C#
  • Comparison Operators in C#
  • Logical Operators in C#

Assignment Operators

Moving Forward, now let’s talk about Assignment Operators which are used to assign values to the variables.

There are 6 Assignment Operators that you will find useful as a Game Developer :

  • Equal To Operator ( = )
  • Addition Operator ( += )
  • Subtraction Operator ( -= )
  • Multiplication Operator ( *= )
  • Division Operator ( /= )
  • Modulus Operator ( %= )

assignment operator | Equal To ( = )

Using the Equal To Assignment Operator ( = ) you can assign value that is on the right side of the Operator to the variable on the left side of the Operator.

In the code above, we are performing addition twice and are using the Equal To ( = ) Assignment Operator

to set the resulting values of those Arithmetic Operations to _playerHP variable.

assignment operator | Addition ( += )

Using the Addition Assignment Operator ( += ) you can perform addition between the variable on the left side of the Operator with the values or variables on the right side of the Operator.

After that Addition is done, the resulting value will be assigned to the variable on the left side of the Operator.

In the code above, we first set _enemyHP to 100 and then in the Start() Method

we are using the Addition Assignment Operator ( += ) to perform addition between _enemyHP and 30

which gives us 130, that we then set to the _enemyHP variable.

assignment operator | Subtraction ( -= )

Using the Subtraction Assignment Operator ( -= ) you can perform subtraction between the variable on the left side of the Operator with the values or variables on the right side of the Operator.

After that Subtraction is done, the resulting value will be assigned to the variable on the left side of the Operator.

In the code above, we first set _weaponHP to 150 and then in the Start() Method

we are using the Subtraction Assignment Operator ( -= ) to perform subtraction between _weaponHP and 45

which gives us 105, that we then set to the _weaponHP variable.

assignment operator | Multiplication ( *= )

Using the Multiplication Assignment Operator ( *= ) you can perform multiplication between the variable on the left side of the Operator with the values or variables on the right side of the Operator.

After that Multiplication is done, the resulting value will be assigned to the variable on the left side of the Operator.

In the code above, we first set _weaponDamage to 10 and then in the Start() Method

we are using the Multiplication Assignment Operator ( *= ) to perform multiplication between _weaponDamage and 4

which gives us 40, that we then set to the _weaponDamage variable.

assignment operator | Division ( /= )

Using the Division Assignment Operator ( /= ) you can perform division between the variable on the left side of the Operator with the values or variables on the right side of the Operator.

After that Division is done, the resulting value will be assigned to the variable on the left side of the Operator.

In the code above, we first set _attackDamage to 125 and then in the Start() Method

we are using the Division Assignment Operator ( /= ) to perform division between _attackDamage and 5

which gives us 25, that we then set to the _attackDamage variable.

assignment operator | Modulus ( %= )

Using the Modulus Assignment Operator ( %= ) you can perform modulo calculation between the variable on the left side of the Operator with the values or variables on the right side of the Operator.

Note : Modulus is finding the remainder of a division calculation between two numbers.

After that modulo calculation is done, the resulting value will be assigned to the variable on the left side of the Operator.

In the code above, we first set _moduloExample to 13 and then in the Start() Method

we are using the Modulus Assignment Operator ( %= ) to perform modulo calculation between _moduloExample and 3

which gives us 1, that we then set to the _moduloExample variable.

Code Without Assignment Operators

Same code but with assignment operators.

If you ask me i like the verbose method more as it is really easy to read through

but of course there are people that like using these assignment operators instead.

Now, let’s execute the code in the image below and check the Unity Console Logs.

Executed Code

This Image show the code containing all the assignment operators which is to be executed in Unity Game Engine.

As you can see all the Arithmetic Calculations done using the Assignment Operators gave the expected output.

This means that, if you so wish,

you can use the Assignment Operators Instead of the Arithmetic Operators where it makes sense in your code.

Well folks, that does it for this article.

i hope that this information will be helpful to you.

Share this post and follow us on Social Media platforms if you think our content is great, so that you never lose the source of something you love.

If you like the content do go through the various articles in How To Make A Game Series that this post is a part of and also go through the other series we have on Bite Sized Tech. Also we have a YouTube Channel : Bite Sized Tech where we upload Informational Videos and Tutorials like this regularly. So, if you are interested do subscribe and go through our Uploads and Playlists.

Follow Us On Social Media

Goodbye for now, This is your host VP Signing off.

Articles In How To Make A Game Series

Intro To Game Development

Game Development Softwares (Game Engines, 2D Art, 3D Art, Code Editor, DAW)

Variables & Data Types

Arithmetic Operators

Comparison Operators

Logical Operators

If Statements

Switch Statements

Foreach Loops

While Loops

Do While Loops

Methods | Part 1 – Basics of Methods

Methods | Part 2 – Multiple, Required & Optional Parameters + Named Arguments

Methods | Part 3 – Overload Resolution

Methods | Part 4 – In, Ref and Out Keywords

Classes, Objects & Constructors

Static Modifier

Access Modifiers

Inheritance

Polymorphism

Abstract Classes & Abstract Methods

Articles in Game Development Tips Series

5 Ways To Develop Games On Low End / Low Spec PCs with Unity

3 Points To Focus On When Designing A Game

Add Some Unpredictability To Your Games

3 Points To Consider Before Committing To A Game Idea

Understanding The Target Player Base Of Your Game

Related Posts

How to make a 3D Model or an Array of 3D Model Follow A Curve - Featured Image

How To Make a 3D Model Or an Array of 3D Model Follow A Curve | Blender Tutorial

Curves and it’s various types like Bezier or Path Curves are extremely versatile in their use and can help 3D Artists in making non destructive and fast iterations in their 3D Scenes. They can be extremely useful in cases such…

Normal Map - CG - Basics Of 3D Art For Game Development Tutorial - Featured Image

Normal Maps and Bump Maps | 3D Art Basics With Blender

Normal Maps and Bump Maps are quite commonly used in 3D Art and Game Development to bring in an incredible amount of detail to the 3D Models without negatively affecting the underlying performance. In this Article, we will be going…

Basics of 3D Art - 3D Modeling, UV Unwrapping, Texturing, Rendering - Featured Image

Overviewing The Basics Of 3D Art | 3D Modeling, UV Unwrapping, Texturing & Rendering

3D Art is a field that a lot of aspiring artists are pursuing with all their Heart and Soul But as the saying goes – “Rome was not built in one day”. Just like that learning how to create 3D…

Albedo Map - Article Featured Image - CG - Basics Of 3D Art For Game Development Tutorial

Albedo Map or Diffuse or Color | 3D Art Basics With Blender

Albedo Maps / Textures or as some might call it Diffuse Maps / Textures are one of the most commonly used items when it comes to computer graphics and 3D Art In this Article, we will be going over What…

Abstract Class and Abstract Method - Unity C# Game Development Tutorial - How To Make A Game - Featured Image

Abstract Class & Abstract Method in C# | Unity Game Development Tutorial | How To Make A Game

Abstract Class is one of the fundamental concept of OOPS (Object Oriented Programming System) and we use it to create Completely or Partially implemented Classes in C#, which give Game Developer such as us more control over how our Classes…

Polymorphism - Unity C# Game Development Tutorial - How To Make A Game - Featured Image

Polymorphism In C# | Unity Game Development Tutorial | How To Make A Game

Polymorphism is a Concept that comes into play when we start using Inheritance in our code and using this concept correctly can give Game Developers the ability to alter Inherited Methods to better suite the Derived Class. In this Article,…

Matomo

unity compound assignment

  • Table of Contents
  • Course Home
  • Assignments
  • Peer Instruction (Instructor)
  • Peer Instruction (Student)
  • Change Course
  • Instructor's Page
  • Progress Page
  • Edit Profile
  • Change Password
  • Scratch ActiveCode
  • Scratch Activecode
  • Instructors Guide
  • About Runestone
  • Report A Problem
  • 1.1 Getting Started
  • 1.1.1 Preface
  • 1.1.2 About the AP CSA Exam
  • 1.1.3 Transitioning from AP CSP to AP CSA
  • 1.1.4 Java Development Environments
  • 1.1.5 Growth Mindset and Pair Programming
  • 1.1.6 Pretest for the AP CSA Exam
  • 1.1.7 Survey
  • 1.2 Why Programming? Why Java?
  • 1.3 Variables and Data Types
  • 1.4 Expressions and Assignment Statements
  • 1.5 Compound Assignment Operators
  • 1.6 Casting and Ranges of Values
  • 1.7 Unit 1 Summary
  • 1.8 Mixed Up Code Practice
  • 1.9 Toggle Mixed Up or Write Code Practice
  • 1.10 Coding Practice
  • 1.11 Multiple Choice Exercises
  • 1.4. Expressions and Assignment Statements" data-toggle="tooltip">
  • 1.6. Casting and Ranges of Values' data-toggle="tooltip" >

Before you keep reading...

Runestone Academy can only continue if we get support from individuals like you. As a student you are well aware of the high cost of textbooks. Our mission is to provide great books to you for free, but we ask that you consider a $10 donation, more if you can or less if $10 is a burden.

Making great stuff takes time and $$. If you appreciate the book you are reading now and want to keep quality materials free for other students please consider a donation to Runestone Academy. We ask that you consider a $10 donation, but if you can give more thats great, if $10 is too much for your budget we would be happy with whatever you can afford as a show of support.

Time estimate: 45 min.

1.5. Compound Assignment Operators ¶

Compound assignment operators are shortcuts that do a math operation and assignment in one step. For example, x += 1 adds 1 to the current value of x and assigns the result back to x . It is the same as x = x + 1 . This pattern is possible with any operator put in front of the = sign, as seen below. If you need a mnemonic to remember whether the compound operators are written like += or =+ , just remember that the operation ( + ) is done first to produce the new value which is then assigned ( = ) back to the variable. So it’s operator then equal sign: += .

Since changing the value of a variable by one is especially common, there are two extra concise operators ++ and -- , also called the plus-plus or increment operator and minus-minus or decrement operator that set a variable to one greater or less than its current value.

Thus x++ is even more concise way to write x = x + 1 than the compound operator x += 1 . You’ll see this shortcut used a lot in loops when we get to them in Unit 4. Similarly, y-- is a more concise way to write y = y - 1 . These shortcuts only exist for + and - as they don’t really make sense for other operators.

If you’ve heard of the programming language C++, the name is an inside joke that C, an earlier language which C++ is based on, had been incremented or improved to create C++.

Here’s a table of all the compound arithmetic operators and the extra concise incremend and decrement operators and how they relate to fully written out assignment expressions. You can run the code below the table to see these shortcut operators in action!

Run the code below to see what the ++ and shorcut operators do. Click on the Show Code Lens button to trace through the code and the variable values change in the visualizer. Try creating more compound assignment statements with shortcut operators and work with a partner to guess what they would print out before running the code.

If you look at real-world Java code, you may occassionally see the ++ and -- operators used before the name of the variable, like ++x rather than x++ . That is legal but not something that you will see on the AP exam.

Putting the operator before or after the variable only changes the value of the expression itself. If x is 10 and we write, System.out.println(x++) it will print 10 but aftewards x will be 11. On the other hand if we write, System.out.println(++x) , it will print 11 and afterwards the value will be 11.

In other words, with the operator after the variable name, (called the postfix operator) the value of the variable is changed after evaluating the variable to get its value. And with the operator before the variable (the prefix operator) the value of the variable in incremented before the variable is evaluated to get the value of the expression.

But the value of x after the expression is evaluated is the same in either case: one greater than what it was before. The -- operator works similarly.

The AP exam will never use the prefix form of these operators nor will it use the postfix operators in a context where the value of the expression matters.

exercise

1-5-2: What are the values of x, y, and z after the following code executes?

  • x = -1, y = 1, z = 4
  • This code subtracts one from x, adds one to y, and then sets z to to the value in z plus the current value of y.
  • x = -1, y = 2, z = 3
  • x = -1, y = 2, z = 2
  • x = 0, y = 1, z = 2
  • x = -1, y = 2, z = 4

1-5-3: What are the values of x, y, and z after the following code executes?

  • x = 6, y = 2.5, z = 2
  • This code sets x to z * 2 (4), y to y divided by 2 (5 / 2 = 2) and z = to z + 1 (2 + 1 = 3).
  • x = 4, y = 2.5, z = 2
  • x = 6, y = 2, z = 3
  • x = 4, y = 2.5, z = 3
  • x = 4, y = 2, z = 3

1.5.1. Code Tracing Challenge and Operators Maze ¶

Use paper and pencil or the question response area below to trace through the following program to determine the values of the variables at the end.

Code Tracing is a technique used to simulate a dry run through the code or pseudocode line by line by hand as if you are the computer executing the code. Tracing can be used for debugging or proving that your program runs correctly or for figuring out what the code actually does.

Trace tables can be used to track the values of variables as they change throughout a program. To trace through code, write down a variable in each column or row in a table and keep track of its value throughout the program. Some trace tables also keep track of the output and the line number you are currently tracing.

../_images/traceTable.png

Trace through the following code:

1-5-4: Write your trace table for x, y, and z here showing their results after each line of code.

After doing this challenge, play the Operators Maze game . See if you and your partner can get the highest score!

1.5.2. Summary ¶

Compound assignment operators ( += , -= , *= , /= , %= ) can be used in place of the assignment operator.

The increment operator ( ++ ) and decrement operator ( -- ) are used to add 1 or subtract 1 from the stored value of a variable. The new value is assigned to the variable.

The use of increment and decrement operators in prefix form (e.g., ++x ) and inside other expressions (i.e., arr[x++] ) is outside the scope of this course and the AP Exam.

Why the subtracting compound assignment operator is used to ADD a angle in unity?

Hello, I’m reading the book “Unity in Action: Multiplatform Game Development in C#”, and I can’t understand how the “-=” operator works with angles to perform a rotation , and the author doesn’t explain this either. I know what the “-=” operator does (subtract an assign a value to the left variable), but why is used here:

I think that has to do with how unity handles the angles of rotation. What not use the “+=” compound assignment operator that is in fact the operator to ADD a value, an instead uses the “-=” operator that is for subtract a value, what is subtracting? Then all the values of “_rotationX” are negatives? inclusive the posives that the input function “GetAxis” retrieves?

I have checked an the script only works with the “-=” operator, something is going on behind the scenes that the book doesn’t explain, can anyone tell me how this work in unity?

Her is what the book says about this:

“The Rotate() method increments the current rotation, whereas this code sets the rotation angle directly. In other words, it’s the difference between saying “add 5 to the angle” and “set the angle to 30.” We do still need to increment the rotation angle, but that’s why the code has the -= operator: to subtract a value from the rotation angle, rather than set the angle to that value . By not using Rotate() we can manipulate the rotation angle in various ways aside from only incrementing it.”

Any help would be greatly appreciated!

They are using -= to get the rotation to happen to the desired direction compared to the mouse movement. It’s just a question of “do we want negative to mean up or down”. You could get the same behavior by putting the negative sign in other places and using +=

Using -= doesn’t mean you can only get negative values. In general, if you subtract a negative value from value X, the result is greater than X. In this case they want rotation_x to grow when “Mouse Y” input is less than 0 because that causes the object to rotate in the direction they wanted.

C# 8 - Null coalescing/compound assignment

There are a lot of cool new features in C# 8 and one of my favorites is the new Null coalescing assignment operator.

Stefán Jökull Sigurðarson

Stefán Jökull Sigurðarson

Hi friends.

There are a lot of cool new features in C# 8 and one of my favorites is the new Null coalescing assignment (or compound assignment, whichever you prefer) operator. If you have ever written code like this:

You can simplify this code A LOT!

That is the new ??= operator in action, which takes care of doing the null check and assignment for you in one sweet syntactic sugar-rush! I also find it more readable, but some people might disagree, and that fine. Just pick whatever you prefer :)

And the best part is that it actually compiles down to the same efficient code! Just take a look at this sharplab.io sample to see what I mean.

You might have solved this with a Lazy<string> or by using something like _someValue = _someValue ?? InitializeMyValue(); as well but that's still more code to write than the new operator and less efficient as well. The Lazy<T> approach has some overhead and the null-coalescing operator + assignment has the added inefficiency of always making the variable assignment even if there is no need to (you can take a closer look at the ASM part of the SharpLab example above) but there it is for reference:

Hope this helps! :)

Sign up for more like this.

  • Case Studies
  • Support & Services
  • Asset Store

unity compound assignment

Search Unity

unity compound assignment

A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate in the Unity community.

  • Discussions
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

You are using an out of date browser. It may not display this or other websites correctly. You should upgrade or use an alternative browser .

  • Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post . Dismiss Notice
  • Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more. Dismiss Notice
  • Search titles only

Separate names with a comma.

  • Search this thread only
  • Display results as threads

Useful Searches

  • Recent Posts

Clamping angle between two values

Discussion in ' Scripting ' started by SHBYT , Mar 25, 2020 .

SHBYT

I have a 2D turret object and I want to limit the amount that the barrel can rotate left and right but Unity is refusing to let me do that. Instead of clamping the rotation of the barrel to -70 degrees (right) and +70 degrees (left) it will only clamp the turret to 0 and +70. Meaning the turret can only ever point left, it will refuse to point right. I have no idea why it's doing this. Code: Code (CSharp): float angle = transform . Find ( "barrelPivot" ) . eulerAngles . z ;   angle = Mathf . Clamp ( angle, - 70f, 70f ) ;   transform . Find ( "barrelPivot" ) . localRotation = Quaternion . Euler ( 0 , 0 , angle ) ;   So I have -70 and +70 yet it clamps my angle to +70? And will not let the barrel rotate to -70? Brilliant! I love that logic! Even if I check to see if the angle to above 70 or below -70 and then set it to the max or min if it exceeds it still messes up. Is it taking the absolute value of my angle or something? Because it keeps going positive! What is going on...  

lordofduct

-270, 90, 450 What do these 3 values have in common? They're all in the same position as 90 degrees. -70 and 290 are the same value. eulerAngles isn't guaranteed to return a value from -180 to 180, it could be in the range 0 to 360. If you want it in the range of -180 to 180 you'll need to normalize it. A simple formula for that is: Code (csharp): //return angle in range -180 to 180 float NormalizeAngle ( float a ) {     return a - 180f * Mathf . Floor ( ( a + 180f ) / 180f ) ; } With that said, clamping based on euler angles is usually a bad idea in 3-space. So if you're doing this in 3-space this will still fail under certain conditions just due to the nature of euler angles. Just like how -70 and 290 are the same rotation. Well in 3-space a rotation around 1 axis could be represented by a completely different rotation around 2 other axes. This fact is why a thing called " gimbal lock " exists. Euler angles are just not mathematically consistent. There is no "logic" to it in terms of continuity. This is what the Quaternion was such a huge discovery in the math world. It brought a continuity to rotations in 3-space that euler angles don't have. And it's why all rotations in Unity are stored as Quaternions. The "eulerAngles" option is only there as a conversion for human readability. If you're only rotating around 1 axis though (such as only the z-axis because you're making a 2d game along the x/y plane). Then normalizing the angle is all that's necessary.  

Yoreki

SHBYT said: ↑ I have a 2D turret object and I want to limit the amount that the barrel can rotate left and right but Unity is refusing to let me do that. Click to expand...

orionsyndrome

orionsyndrome

I wish everyone in the universe would see this thread and solve this once and for all ANGLES ARE MODULAR !!! I mean what's so hard to reason about: If you tell someone it's 257 o'clock, what time it is? it's 5 PM 10 days in the future. how do I know that? well you have 10 full revolutions in 257 hours, but you're interested in what remains. so 17 hours because 257 - 24 * 10 = 17 now that's a brilliant logic, wouldn't you agree? Code (csharp): static public float ModularClamp ( float val, float min, float max, float rangemin = - 180f, float rangemax = 180f ) {   var modulus = Mathf . Abs ( rangemax - rangemin ) ;   if ( ( val %= modulus ) < 0f ) val += modulus ;   return Mathf . Clamp ( val + Mathf . Min ( rangemin, rangemax ) , min, max ) ; } Code (csharp): angle = ModularClamp ( angle, - 70f, 70f ) ; if you're working with angles in degrees make sure the last two arguments add up to 360 (not min and max, but rangemin and rangemax) otherwise you'll clip the phase and make a nonsense in other words, you can also use this like this Code (csharp): angle = ModularClamp ( angle, 45f, 135f, 0f, 360f ) ;  

ItsJacGaming

ItsJacGaming

orionsyndrome said: ↑ I wish everyone in the universe would see this thread and solve this once and for all ANGLES ARE MODULAR !!! I mean what's so hard to reason about: If you tell someone it's 257 o'clock, what time it is? it's 5 PM 10 days in the future. how do I know that? well you have 10 full revolutions in 257 hours, but you're interested in what remains. so 17 hours because 257 - 24 * 10 = 17 now that's a brilliant logic, wouldn't you agree? Code (csharp): static public float ModularClamp ( float val, float min, float max, float rangemin = - 180f, float rangemax = 180f ) {   var modulus = Mathf . Abs ( rangemax - rangemin ) ;   if ( ( val %= modulus ) < 0f ) val += modulus ;   return Mathf . Clamp ( val + Mathf . Min ( rangemin, rangemax ) , min, max ) ; } Code (csharp): angle = ModularClamp ( angle, - 70f, 70f ) ; if you're working with angles in degrees make sure the last two arguments add up to 360 (not min and max, but rangemin and rangemax) otherwise you'll clip the phase and make a nonsense in other words, you can also use this like this Code (csharp): angle = ModularClamp ( angle, 45f, 135f, 0f, 360f ) ; Click to expand...
feel free to ask the magic sauce in the code above is this Code (csharp): if ( ( val %= modulus ) < 0f ) val += modulus ; this corrects the situation that C# doesn't support on its own. it has the % operator, however this isn't a so-called modulo operator, but is instead a division remainder operator. it sounds similar and sometimes works like modulo, but it's not modulo. when you work with modular numbers you want to pretend that working with a continuum of values yields an endless loop of a limited range of values. just like the face of a clock, if that's easier to visualize. but working with division remainder has a mirror symmetry around the zero. so it doesn't behave when you move toward the negative part. here's an example: in 24 hr format -1 o'clock should be equal to 23. observe (24+23) % 24 gives the correct modular result of 23 but -1 % 24 returns -1 , while a true modulo would return 23 instead to correct this we can do the following test Code (csharp): var remainder = value % modulus ; // i.e. 47 % 24 will normally return 23 // but if it was -1 % 24 we'll get -1 as a result, so we can add 24 to this to get to 23 if ( remainder < 0 ) remainder = remainder + modulus ; thanks to compound assignment, we can bundle the first line into value %= modulus; and the second one into value += modulus; if we bundle these two together we end up with Code (csharp): if ( ( val %= modulus ) < 0f ) val += modulus ; and that's a proper modulo operation as a one-liner NOTE: this will work with both integers and floating point values, but it is sometimes important to distinguish between the two.  

SgtOkiDoki

Here, this should do the job. Code (CSharp):   public static float ClampAngle ( float current, float min, float max ) {     float dtAngle = Mathf . Abs ( ( ( min - max ) + 180 ) % 360 - 180 ) ;     float hdtAngle = dtAngle * 0 . 5f ;     float midAngle = min + hdtAngle ;       float offset = Mathf . Abs ( Mathf . DeltaAngle ( current, midAngle ) ) - hdtAngle ;     if ( offset > 0 )         current = Mathf . MoveTowardsAngle ( current, midAngle, offset ) ;     return current ; }    

atomicjoe

orionsyndrome said: ↑ observe (24+23) % 24 gives the correct modular result of 23 but -1 % 24 returns -1 , while a true modulo would return 23 instead to correct this we can do the following test thanks to compound assignment, we can bundle the first line into value %= modulus; and the second one into value += modulus; Click to expand...
  • x = ( x + ( y * i ) ) % y
  • being ' y ' the modulus and ' i ' an integer larger or equal to 1 depending on how large the negative number is expected to be
atomicjoe said: ↑ depending on how large the negative number is expected to be Click to expand...
orionsyndrome said: ↑ if you know how large is x, why do you need %? for your example, you would have to do integer division twice (% already does it) and compute i as x / m, but there are problems with this. Click to expand...
  • x = ( x + ( y * 1000000 ) ) % y
atomicjoe said: ↑ I'm being practical here: you usually know what are the ranges of expected values for your variables. Click to expand...
  • using System ;
  • using System.Runtime.CompilerServices ;
  • namespace WhateverExtensions {
  •   static public class ModuloNumbers {
  •     [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
  •     static public int Mod ( this int n, int m ) {
  • #if DEBUG || UNITY_EDITOR
  •       if ( m <= 0 ) throw new ArgumentOutOfRangeException ( nameof ( m ) , "Modulus has to be greater than zero." ) ;
  •       if ( ( n %= m ) < 0 ) n += m ;
  •       return n ;
  •     }
  •     static public int NextOf ( this int n, int m, int i = 1 ) => ( n + i ) . Mod ( m ) ;
  •     static public int PrevOf ( this int n, int m, int i = 1 ) => ( n - i ) . Mod ( m ) ;
  •   }
  • /// <summary>
  • /// Returns the interpolated point on the chosen edge segment. (Not clamped.)
  • /// </summary>
  • /// <returns>The point.</returns>
  • /// <param name="edgeIndex">Index of edge.</param>
  • /// <param name="lerp">A value between 0 and 1.</param>
  • public Vector3 GetPointOnEdge ( int edgeIndex, float lerp )
  •   => _tri [ edgeIndex ] . LerpTo ( _tri [ edgeIndex . NextOf ( 3 ) ] , lerp ) ;
  • using WhateverExtensions ;
  • namespace GeomLibrary {
  •   using Vector2     = UnityEngine . Vector2 ;
  •   using Vector3     = UnityEngine . Vector3 ;
  •   using Quaternion = UnityEngine . Quaternion ;
  •   using Matrix4x4   = UnityEngine . Matrix4x4 ;
  •   static public partial class Geom3D {
  •     // General purpose 3D triangle; mutable
  •     public struct Triangle : IEquatable < Triangle > {
  •       const int VERTICES = 3 ;
  •       public Vector3 p1, p2, p3 ;
  •       public Triangle ( Vector3 a, Vector3 b, Vector3 c ) { p1 = a ; p2 = b ; p3 = c ; }
  •       public Triangle ( Triangle t ) : this ( t . p1 , t . p2 , t . p3 ) { }
  •       public Triangle ( int index, params Vector3 [ ] points ) : this ( points [ index ] , points [ index + 1 ] , points [ index + 2 ] ) { }
  •       public Triangle ( int i1, int i2, int i3, Vector3 [ ] points ) : this ( points [ i1 ] , points [ i2 ] , points [ i3 ] ) { }
  •       public Triangle ( Vector3 p, Vector3 dir1, float length1, Vector3 dir2, float length2, bool flip = false ) {
  •         p1 = p ;
  •         p2 = p + length1 * dir1 ;
  •         p3 = p + length2 * dir2 ;
  •         if ( flip ) Flip ( ) ;
  •       }
  •       public Vector3 this [ int index ] {
  •         get {
  •           switch ( index ) {
  •             case 0 : return p1 ;
  •             case 1 : return p2 ;
  •             case 2 : return p3 ;
  •             default : throw new IndexOutOfRangeException ( ) ;
  •           }
  •         }
  •         set {
  •             case 0 : p1 = value ; break ;
  •             case 1 : p2 = value ; break ;
  •             case 2 : p3 = value ; break ;
  •       public Vector3 Centroid ( ) => MathEx . THIRD * ( p1 + p2 + p3 ) ;
  •       public Vector3 Edge ( int index ) => this [ index . Mod ( VERTICES ) ] . To ( this [ index . NextOf ( VERTICES ) ] ) ;
  •       public Segment GetSegment ( int index ) => new Segment ( this [ index . Mod ( VERTICES ) ] , this [ index . NextOf ( VERTICES ) ] ) ;
  •       public void Flip ( ) { var t = p3 ; p3 = p2 ; p2 = t ; }
  •       public Triangle GetFlippedIf ( bool condition )
  •         => condition ? - this : this ;
  •       public void Turn ( ) { var t = p3 ; p3 = p2 ; p2 = p1 ; p1 = t ; }
  •       public Triangle GetTurnedIf ( bool condition )
  •         => condition ? new Triangle ( p3, p1, p2 ) : this ;
  •       static public Triangle operator - ( Triangle tri ) => new Triangle ( tri . p1 , tri . p3 , tri . p2 ) ;
  •       static public Triangle operator + ( Triangle tri, Vector3 offset ) => Lambda ( ( i ) => tri [ i ] + offset ) ;
  •       static public Triangle operator - ( Triangle tri, Vector3 offset ) => Lambda ( ( i ) => tri [ i ] - offset ) ;
  •       static public Triangle operator * ( float factor, Triangle tri ) => Lambda ( ( i ) => factor * tri [ i ] ) ;
  •       static public Triangle operator * ( Quaternion rotation, Triangle tri ) => Lambda ( ( i ) => rotation * tri [ i ] ) ;
  •       static public Triangle operator * ( Matrix4x4 matrix, Triangle tri ) => Lambda ( ( i ) => matrix . MultiplyPoint ( tri [ i ] ) ) ;
  •       public void Translate ( Vector3 delta ) => Lambda ( ( i,v ) => delta + v ) ;
  •       public void Scale ( float factor ) => Lambda ( ( i,v ) => factor * v ) ;
  •       public void Rotate ( Quaternion rotation ) => Lambda ( ( i,v ) => rotation * v ) ;
  •       public void RotateAround ( Vector3 center, Quaternion rotation )
  •         => Lambda ( ( i,v ) => rotation * ( v - center ) + center ) ;
  •       public void Lambda ( Func < int , Vector3, Vector3 > lambda ) {
  •         p1 = lambda ( 0 , p1 ) ; p2 = lambda ( 1 , p2 ) ; p3 = lambda ( 2 , p3 ) ;
  •       static public Triangle Lambda ( Func < int , Vector3 > lambda ) => new Triangle ( lambda ( 0 ) , lambda ( 1 ) , lambda ( 2 ) ) ;
  •       public Vector3 [ ] ToArray ( ) => new Vector3 [ ] { p1, p2, p3 } ;
  •       public void CopyTo ( Vector3 [ ] array ) => Lambda ( ( i,v ) => array [ i ] = v ) ;
  •       public void CopyTo ( Vector3 [ ] array, int index ) => Lambda ( ( i,v ) => array [ index + i ] = v ) ;
  •       static public Triangle FromArray ( params Vector3 [ ] array ) {
  •         if ( array is null ) throw new ArgumentNullException ( ) ;
  •         if ( array . Length != VERTICES ) throw new ArgumentException ( ) ;
  •         return new Triangle ( array [ 0 ] , array [ 1 ] , array [ 2 ] ) ;
  •       public ( Vector3 a, Vector3 b, Vector3 c ) ToTuple ( ) => ( p1, p2, p3 ) ;
  •       static public Triangle FromTuple ( ( Vector3 a, Vector3 b, Vector3 c ) tuple )
  •         => new Triangle ( tuple . a , tuple . b , tuple . c ) ;
  •       static public bool operator == ( Triangle a, Triangle b ) => a . Equals ( b ) ;
  •       static public bool operator != ( Triangle a, Triangle b ) => ! a . Equals ( b ) ;
  •       public override bool Equals ( object obj ) {
  •         if ( obj is Triangle tri ) return Equals ( tri ) ;
  •         return false ;
  •       public bool Equals ( Triangle other )
  •         => p1 . IsApproximately ( other . p1 , 1E - 8f ) &&
  •            p2 . IsApproximately ( other . p2 , 1E - 8f ) &&
  •            p3 . IsApproximately ( other . p3 , 1E - 8f ) ;
  •       public override int GetHashCode ( ) { // sdbm
  •         int hash = 0x12766 ;
  •         unchecked {
  •           hash = p1 . GetHashCode ( ) + ( hash << 6 ) + ( hash << 16 ) - hash ;
  •           hash = p2 . GetHashCode ( ) + ( hash << 6 ) + ( hash << 16 ) - hash ;
  •           hash = p3 . GetHashCode ( ) + ( hash << 6 ) + ( hash << 16 ) - hash ;
  •         return hash ;
  •       public override string ToString ( ) => ToString ( "F3" ) ;
  •       public string ToString ( string format )
  •         => $ "[Tri {p1.ToString(format)} {p2.ToString(format)} {p3.ToString(format)}]" ;
I don't understand why did you have to drag me into this "heated" discussion with zero arguments. You pretend to ask a question only to have it your way while insulting me. If I'm the one who has a problem then why are you attacking me personally for no apparent reason? I will never understand why you trolls exist and what's your point other than to artificially boost your egos, which is so petty that you're literally insulting yourself. How can you live like that? Does it feel good? I couldn't tell. How about minding your own business and doing things your way without rubbing anyone's nose in it? Listen, it's obvious that you don't really care at this point, but I'll write this for the record anyway, and who knows maybe the third time is the charm: your way of thinking through this is appalling. What you think will lead you to performance is colloquially known as "cowboy coding." wikipedia said: Inexperience might also lead to disregard of accepted standards, making the project source difficult to read or causing conflicts between the semantics of the language constructs and the result of their output. Click to expand...
Uhhhhh... So I think that may have gone awry. To be fair to both of you... you both sound pretty condescending. Like a tit-for-tat situation... you atom were the one who turned it into name calling and saying orion needs professional help (effectively calling them crazy... which is a bit rude). ... I mean don't get me wrong. Ain't like I'm an angel and can certainly be very condescending if not outright rude. So, take that with a grain of salt. So uhhh, how about we all agree to disagree.  
Welcome to the party lordofduct! You may have missed the part were he called me a combination of lazy, ignorant and supersticious in a condescending way. I don't mean to be rude when I say he needs help, I really think so. I'm not joking.  
the mathematician and engineer thing was A JOKE that someone told me. I guess nowadays everything is offensive... Anyway, I'm not the one trying to make this bigger than it is. For my part it's no big deal, but I have a feeling that it is not the same for him. Aaaanyway, to sum this up: to use % as modulo in C#, just be sure that your value is positive.  
Let me return to the crux of the technical issue here: The point of a general purpose function is to be general purpose. What you're advocating is not a general purpose solution. For me, modulo operation is absolutely required to work with negative numbers. The major benefit of computing a modulo is to get the last element of an array by addressing -1, for example. Your solution is quite limited, looks weird, has to be maintained forever, and deserves a comment to be placed to avoid making a major mistake, because humans easily forget such details and are easy to fall for biases and erroneous assumptions. This is not what programming is about. I get that you're (pretend-)passionate about speedy solutions BUT it's not always about squeezing that 1.15 nanoseconds out of a call. That's trivial and it's immature to think this will somehow make the world a better place. When you design a large code base it's about preventing disasters in the long run, and disasters in a large software are INEVITABLE. I'm not the smartest man in the world, but I've been around for long enough that I'm absolutely sure what I'm talking about. I don't like you spreading around this misinformation, giving it so much weight, these forums are for people who know much less than you or me, I don't like them being misguided by your undeserved sense of authority over these things. I don't really care about some joe on the internet, I would just like younger and less experienced people to simply copy/paste what I typed above because that's a responsibly written code, as not only it took me some time to fine-tune it into something I believe to be robust and legible, but because it's also consensually correct for the C# programming culture all over the globe, as attested by that snippet from Stack Exchange. As a side note: I live in a vastly different culture, I am not a native English speaker, and I don't pretend to be someone else. I can't stand sugar-coating and I address others strictly from an intellectual place, as I'm not really a pack animal. I don't circle around my victims trying to find a vulnerable spot and I don't lick my lips. I write how I think and how I think is how I approach problems in life with relative success. This is largely shaped by my life experiences, origins, and preferences. That doesn't mean I'm always right however, but I am not a diplomat nor a politician. Metaphorically, I shoot to kill. Yes, I might be smug or condescending by some accounts, but regardless of how we come across, ultimately it boils down to why we do the things we do. What knowledge did you actually share with the rest of the humanity? I will leave that to the readers to decide.  
orionsyndrome said: ↑ This is not what programming is about. I get that you're (pretend-)passionate about speedy solutions BUT it's not always about squeezing that 1.15 nanoseconds out of a call. That's trivial and it's immature to think this will somehow make the world a better place. Click to expand...
The day you'll have to calculate the modulo for every single pixel on screen, you'll notice the difference in speed. Granted. And of course the function up there is not a general purpose function! it was never meant to be used on spreadsheets! But we're on a game developer's forum here, performance is key, and the function I put up there specifically stated that you need to know the range of values you're expected to have, otherwise, DON'T USE IT! It's the same with variable types: you could be using 64bit variables for everything, but you don't (I hope) because that would be slow! Instead you settle for 32bits floats because it's good enough for your expected range of values! That's what optimization is about: you can't go around using general purpose functions and 64bits variables for everything and expect good performance. Also, about worrying about people using this for everything and making the world explode: any programmer who copy-pastes without understanding what the code does has bigger problems to deal with than a modulo speed oriented function. And about the meaning of coding, you can go all poetic about it, but in the end, you code to make programs that fulfill a need, and the better a program fits that need, the better the program is. (and yes, that need includes being stable!) If your target is to make general purpose functions easy to maintain that don't need extra care, you're doing it perfectly. But if your target is to make high performance graphical applications you're missing the mark. Tolerances aren't the same on a general purpose car than on an F1 car. One is not better than the other in a vacuum: they are built for specific tasks, and both excel in what they must do. You can't just put components from one into the other and expect them to work. You have to custom-fit things, and, ultimately, this is, for me, what programming is all about.  
atomicjoe said: ↑ But we're on a game developer's forum here, performance is key Click to expand...

rafaelcraftero_unity

rafaelcraftero_unity

so what's the best method to clamp two angles xd?  

Kurt-Dekker

Kurt-Dekker

rafaelcraftero_unity said: ↑ so what's the best method to clamp two angles xd? Click to expand...
thank you  

Bunny83

Since this thread is already "necroed": I really don't want to heat up the discussion again, however this statement is (unfortunately) wrong: atomicjoe said: ↑ Aaaanyway, to sum this up: to use % as modulo in C#, just be sure that your value is positive. Click to expand...
  • v = q * b + r
Bunny83 said: ↑ this statement is (unfortunately) wrong: Click to expand...

pep

Find what you need to study

1.4 Compound Assignment Operators

7 min read • december 27, 2022

Athena_Codes

Athena_Codes

user_sophia9212

user_sophia9212

Compound Assignment Operators

Compound Operators

Sometimes, you will encounter situations where you need to perform the following operation:

This is a bit clunky with the repetition of integerOne in line two. We can condense this with this statement:

The "* = 2" is an example of a compound assignment operator , which multiplies the current value of integerOne by 2 and sets that as the new value of integerOne. Other arithmetic operators also have compound assignment operators as well, with addition, subtraction, division, and modulo having +=, -=, /=, and %=, respectively.

Incrementing and Decrementing

There are special operators for the two following operations in the following snippet well:

These can be replaced with a pre-increment /pre-decrement (++i or - -i) or post-increment /post-decrement (i++ or i- -) operator . You only need to know the post-variant in this course, but it is useful to know the difference between the two. Here is an example demonstrating the difference between them:

By itself, there is no difference between the pre-increment and post-increment operators, but it's evident when you use it in a method such as the println method. For this statement, I will write a debugging output , which happens when we trace the code, which means to follow it line-by-line.

Code Tracing Practice

Now that you’ve learned about code tracing , let’s do some practice! You can use trace tables like the ones shown below to keep track of the values of your variables as they change.

Here are some practice problems that you can use to practice code tracing . Feel free to use whichever method you’re the most comfortable with!

Trace through the following code:

Note: Your answers could look different depending on how you’re tracking your code tracing .

a *= 3: This line multiplies a by 3 and assigns the result back to a. The value of a is now 18.

b -= 2: This line subtracts 2 from b and assigns the result back to b. The value of b is now 2.

c = a % b: This line calculates the remainder of a divided by b and assigns the result to c. The value of c is now 0.

a += c: This line adds c to a and assigns the result back to a. The value of a is now 18.

b = a - b: This line subtracts b from a and assigns the result back to b. The value of b is now 16.

c *= b: This line multiplies c by b and assigns the result back to c. The value of c is now 0.

The final values of the variables are:

double x = 15.0;

double y = 4.0;

double z = 0;

x /= y: This line divides x by y and assigns the result back to x. The value of x is now 3.75.

y *= x: This line multiplies y by x and assigns the result back to y. The value of y is now 15.0.

z = y % x: This line calculates the remainder of y divided by x and assigns the result to z. The value of z is now 3.75.

x += z: This line adds z to x and assigns the result back to x. The value of x is now 7.5.

y = x / z: This line divides x by z and assigns the result back to y. The value of y is now 2.0.

z *= y: This line multiplies z by y and assigns the result back to z. The value of z is now 7.5.

int a = 100;

int b = 50;

int c = 25;

a -= b: This line subtracts b from a and assigns the result back to a. The value of a is now 50.

b *= 2: This line multiplies b by 2 and assigns the result back to b. The value of b is now 100.

c %= 4: This line calculates the remainder of c divided by 4 and assigns the result back to c. The value of c is now 1.

a = b + c: This line adds b and c and assigns the result to a. The value of a is now 101.

b = c - a: This line subtracts a from c and assigns the result to b. The value of b is now -100.

c = a * b: This line multiplies a and b and assigns the result to c. The value of c is now -10201.

a *= 2: This line multiplies a by 2 and assigns the result back to a. The value of a is now 10.

b -= 1: This line subtracts 1 from b and assigns the result back to b. The value of b is now 2.

a += c: This line adds c to a and assigns the result back to a. The value of a is now 10.

b = a - b: This line subtracts b from a and assigns the result back to b. The value of b is now 8.

int y = 10;

int z = 15;

x *= 2: This line multiplies x by 2 and assigns the result back to x. The value of x is now 10.

y /= 3: This line divides y by 3 and assigns the result back to y. The value of y is now 3.3333... (rounded down to 3).

z -= x: This line subtracts x from z and assigns the result back to z. The value of z is now 5.

x = y + z: This line adds y and z and assigns the result to x. The value of x is now 8.

y = z - x: This line subtracts x from z and assigns the result to y. The value of y is now -3.

z = x * y: This line multiplies x and y and assigns the result to z. The value of z is now -24.

double x = 10;

double y = 3;

x /= y: This line divides x by y and assigns the result back to x. The value of x is now 3.3333... (rounded down to 3.33).

y *= x: This line multiplies y by x and assigns the result back to y. The value of y is now 10.

z = y - x: This line subtracts x from y and assigns the result to z. The value of z is now 6.67.

x += z: This line adds z to x and assigns the result back to x. The value of x is now 10.0.

y = x / z: This line divides x by z and assigns the result back to y. The value of y is now 1.5.

z *= y: This line multiplies z by y and assigns the result back to z. The value of z is now 10.0.

Want some additional practice? CSAwesome created this really cool Operators Maze game that you can do with a friend for a little extra practice! 

Key Terms to Review ( 5 )

Code Tracing

Decrementing

Post-increment

Pre-increment

Fiveable

Stay Connected

© 2024 Fiveable Inc. All rights reserved.

AP® and SAT® are trademarks registered by the College Board, which is not affiliated with, and does not endorse this website.

Instantly share code, notes, and snippets.

@WeirdBeardDev

WeirdBeardDev / .editorconfig

  • Download ZIP
  • Star ( 0 ) 0 You must be signed in to star a gist
  • Fork ( 1 ) 1 You must be signed in to fork a gist
  • Embed Embed this gist in your website.
  • Share Copy sharable link for this gist.
  • Clone via HTTPS Clone using the web URL.
  • Learn more about clone URLs
  • Save WeirdBeardDev/a1ad3e0a340da2cc1ec269479eee1b14 to your computer and use it in GitHub Desktop.

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Null coalescing assignment

  • 6 contributors

This article is a feature specification. The specification serves as the design document for the feature. It includes proposed specification changes, along with information needed during the design and development of the feature. These articles are published until the proposed spec changes are finalized and incorporated in the current ECMA specification.

There may be some discrepancies between the feature specification and the completed implementation. Those differences are captured in the pertinent language design meeting (LDM) notes .

You can learn more about the process for adopting feature speclets into the C# language standard in the article on the specifications .

Simplifies a common coding pattern where a variable is assigned a value if it is null.

As part of this proposal, we will also loosen the type requirements on ?? to allow an expression whose type is an unconstrained type parameter to be used on the left-hand side.

It is common to see code of the form

This proposal adds a non-overloadable binary operator to the language that performs this function.

There have been at least eight separate community requests for this feature.

Detailed design

We add a new form of assignment operator

Which follows the existing semantic rules for compound assignment operators ( §11.18.3 ), except that we elide the assignment if the left-hand side is non-null. The rules for this feature are as follows.

Given a ??= b , where A is the type of a , B is the type of b , and A0 is the underlying type of A if A is a nullable value type:

  • If A does not exist or is a non-nullable value type, a compile-time error occurs.
  • If B is not implicitly convertible to A or A0 (if A0 exists), a compile-time error occurs.
  • If A0 exists and B is implicitly convertible to A0 , and B is not dynamic, then the type of a ??= b is A0 . a ??= b is evaluated at runtime as: var tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp Except that a is only evaluated once.
  • Otherwise, the type of a ??= b is A . a ??= b is evaluated at runtime as a ?? (a = b) , except that a is only evaluated once.

For the relaxation of the type requirements of ?? , we update the spec where it currently states that, given a ?? b , where A is the type of a :

If A exists and is not a nullable type or a reference type, a compile-time error occurs.

We relax this requirement to:

  • If A exists and is a non-nullable value type, a compile-time error occurs.

This allows the null coalescing operator to work on unconstrained type parameters, as the unconstrained type parameter T exists, is not a nullable type, and is not a reference type.

As with any language feature, we must question whether the additional complexity to the language is repaid in the additional clarity offered to the body of C# programs that would benefit from the feature.

Alternatives

The programmer can write (x = x ?? y) , if (x == null) x = y; , or x ?? (x = y) by hand.

Unresolved questions

  • [ ] Requires LDM review
  • [ ] Should we also support &&= and ||= operators?

Design meetings

C# feature specifications

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

Logo image

Introduction to C-Programming: As seen in ENGS 20

Petra Bonfert-Taylor

Search Results:

Section 13.4 compound assignment operators.

If you cannot see this codecast, please click here .

Check Your Understanding Check Your Understanding

admin ..... open in new window

unity compound assignment

IMAGES

  1. Compound Object Unity Tool : Alex Woloszynski

    unity compound assignment

  2. Compound Object Unity Tool : Alex Woloszynski

    unity compound assignment

  3. Answered: Pick out the compound assignment…

    unity compound assignment

  4. Compound Collider Gizmo

    unity compound assignment

  5. PPT

    unity compound assignment

  6. Compound Assignment Operators

    unity compound assignment

VIDEO

  1. [Unity Assignment Showcase] John Lemon's Haunted Jaunt

  2. IGB101 Assignment 2 video

  3. Compound Assignment Operators in C++ || C++ Programming #viral #subscribe

  4. SCORCHED SANDS UNITY ASSIGNMENT GAME #vitbhopal #VIT #UNITY

  5. Unity VFX Assignment

  6. UNITY 5 ДЛЯ НАЧИНАЮЩИХ

COMMENTS

  1. What does "Convert into compound assignment" mean?

    See Compound Assignment. For a binary operator op, a compound assignment expression of the form: x += y. is equivalent to. x = x + y. It simply makes your code more compact and (arguably) more readable. answered Mar 31, 2023 at 3:32. Luke Vo.

  2. Use compound assignment (IDE0054 and IDE0074)

    If you want to suppress only a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. C#. Copy. #pragma warning disable IDE0054 // Or IDE0074 // The code that's violating the rule is on this line. #pragma warning restore IDE0054 // Or IDE0074. To disable the rule for a file, folder, or project ...

  3. Assignment operators

    The left-hand operand of ref assignment can be a local reference variable, a ref field, and a ref, out, or in method parameter. Both operands must be of the same type. Compound assignment. For a binary operator op, a compound assignment expression of the form. x op= y is equivalent to. x = x op y except that x is only evaluated once.

  4. c#

    5,55112938. 0. these are shorthand operators. these are used when you does the operation & stores result into one of the variable between them. that is you store result into one of your operand suppose example 1)x=x+y; here you can do x+=y; ex 2) x=x+1; here you can do x+=1; edited Nov 9, 2012 at 13:25.

  5. Coalescing operator and Compound assignment operator in C#

    Coalescing operator and Compound assignment operator in C# # csharp # todayilearned. Hello! Today i want to ask you this: Have you ever used a Null Coalescing operator or even a Compound assignment operator in C# ? ... How it works. 3D Games. A bit about shaders and how the graphics pipeline works in Unity. Devs Daddy - Apr 2. Matheus Gomes ...

  6. Assignment Operators

    Using the Equal To Assignment Operator ( = ) you can assign value that is on the right side of the Operator to the variable on the left side of the Operator. In the code above, we are performing addition twice and are using the Equal To ( = ) Assignment Operator. to set the resulting values of those Arithmetic Operations to _playerHP variable.

  7. 1.5. Compound Assignment Operators

    1.5. Compound Assignment Operators¶. Compound assignment operators are shortcuts that do a math operation and assignment in one step. For example, x += 1 adds 1 to the current value of x and assigns the result back to x.It is the same as x = x + 1.This pattern is possible with any operator put in front of the = sign, as seen below. If you need a mnemonic to remember whether the compound ...

  8. Why the subtracting compound assignment operator is ...

    Hello, I'm reading the book "Unity in Action: Multiplatform Game Development in C#", and I can't understand how the "-=" operator works with angles to perform a rotation , and the author doesn't explain this either. I know what the "-=" operator does (subtract an assign a value to the left variable), but why is used here: ... public float sensitivityHor = 9.0f; public float ...

  9. docs/docs/fundamentals/code-analysis/style-rules/ide0054 ...

    Learn about code analysis rules IDE0054 and IDE0074: Use compound assignment. 09/30/2020. IDE0054. IDE0074. dotnet_style_prefer_compound_assignment. IDE0054. IDE0074. dotnet_style_prefer_compound_assignment. gewarren. gewarren. CSharp. VB. Use compound assignment (IDE0054 and IDE0074) This article describes two related rules, IDE0054 and ...

  10. ?? and ??= operators

    The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.

  11. C# 8

    Hi friends. There are a lot of cool new features in C# 8 and one of my favorites is the new Null coalescing assignment (or compound assignment, whichever you prefer) operator. If you have ever written code like this: private string _someValue; public string SomeMethod() { // Let's do an old-school null check and initialize if needed.

  12. Clamping angle between two values

    If you want it in the range of -180 to 180 you'll need to normalize it. A simple formula for that is: Code (csharp): //return angle in range -180 to 180. float NormalizeAngle (float a) {. return a - 180f * Mathf.Floor(( a + 180f) / 180f); } With that said, clamping based on euler angles is usually a bad idea in 3-space.

  13. PDF Compound assignment operators

    The Java language specification says that: The compound assignment E1 op= E2 is equivalent to [i.e. is syntactic sugar for] E1 = (T) ((E1) op (E2)) where T is the type of E1, except that E1 is evaluated only once. We note two important points: The expression is cast to the type of E1 before the assignment is made (the cast is in red above) E1 ...

  14. Microsoft.Unity.Analyzers/USP0017.md at main

    USP0017 Unity objects should not use coalescing assignment. UnityEngine.Object should not be used with the coalescing assignment operator.. Suppressed Diagnostic ID. IDE0074 - Use compound assignment. Examples of code that produces a suppressed diagnostic

  15. Compound Assignment Operators

    The "*= 2" is an example of a compound assignment operator, which multiplies the current value of integerOne by 2 and sets that as the new value of integerOne. Other arithmetic operators also have compound assignment operators as well, with addition, subtraction, division, and modulo having +=, -=, /=, and %=, respectively. Incrementing and ...

  16. Do not suggest null-coalescing compound assignment in Unity projects

    Hi, just updated to 2019.2 and was impressed by the suggestion to use null-coalescing compound assignments, which can simplify lazy-loaded properties in the following way: public Foo SomeProperty => _backingField ?? ... Do not suggest null-coalescing compound assignment in Unity projects #1391. Closed callumtw opened this issue Nov 5, 2019 · 1 ...

  17. EditorConfig for Unity Project using a Microsoft.Unity.Analyzers

    csharp_style_unused_value_assignment_preference = discard_variable # IDE0060: Remove unused parameter # USP0005: Suppresses IDE0060 - The Unity runtime invokes Unity messages # dotnet_diagnostic.IDE0060.severity = suggestion # dotnet_code_quality_unused_parameters = all # IDE0061: Use expression body for local functions

  18. Boolean logical operators

    A user-defined type can't explicitly overload a compound assignment operator. A user-defined type can't overload the conditional logical operators && and || . However, if a user-defined type overloads the true and false operators and the & or | operator in a certain way, the && or || operation, respectively, can be evaluated for the operands of ...

  19. Unity 2021.3.17

    UI Toolkit: Fixed support for compound assignment operators for UI Toolkit numeric fields (IntegerField, LongField, FloatField, DoubleField). ( UUM-3471 ) UI Toolkit: Improved UI Toolkit so that flipped UVs are now properly handled by scale modes of the Image element.

  20. Compound Assignment Operators

    Here are some different compound assignment operators we can use: += add and assign the sum.-= subtract and assign the difference. *= multiply and assign the product. /= divide and assign the quotient. %= divide and assign the remainder. Check out these operators in action as we modify the value of dollars five times using compound assignment ...

  21. Null coalescing assignment

    This article is a feature specification. The specification serves as the design document for the feature. It includes proposed specification changes, along with information needed during the design and development of the feature. These articles are published until the proposed spec changes are finalized and incorporated in the current ECMA ...

  22. Compound Assignment Operators

    These common coding tasks, where a certain operation (i.e. addition, subtraction, etc.) is being done to one variable itself (so the variable appears on both sides of the assignment operation), can be written in a shorthand using compound assignment operators.