Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by AntLewis · Dec 15, 2013 at 02:28 PM · extension-methods

Extension Method

Hi guys, I've created an extension method for a Vector2 as follows:

     public static void RemoveSmallestComponent ( this Vector2 vector)
     {
         if ( Mathf.Abs ( vector.x ) > Mathf.Abs ( vector.y ) )
         {
             vector.y = 0; 
         }else{
             vector.x=0; 
         }

     }

...and calling it as follows:

 Vector2 test = new Vector2 ( 0.1, 0.9 );
 test.RemoveSmallestComponent();

Within the actual code it's behaving as it should (stripping out the smallest component of the vector) but it's not actually changing the vector that is calling it.

Where am I going wrong? Thanks for any advice!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by vexe · Dec 15, 2013 at 02:56 PM

That's because Vector2 is a value-type - (a struct). And when you deal with value-types, you deal with copies of them, not references. So when you pass a Vector2 to a method and change that vector's value inside, you won't affect the actual Vector2 that you passed because a copy of the vector gets created and passed (i.e. not the same storage location) (which is a reason why they recommend for structs not to be big in size. If they're big, it's gonna be an overhead each time you pass your struct to a method, cause a copy of it has to be created in order to get passed...)

 Vector2 v1 = new Vector2(1, 2);
 Reset(v1);
 print(v1); // still prints 1, 2
 
 void Reset(Vector2 v)
 {
    v.x = v.y = 0;
 }

This is what is happening with your extension - is that a copy of your Vector2 is getting passed. Normally, you'd solve this by passing the parameter by reference, like so:

 void Reset(ref Vector2 v)
 {
    v.x = v.y = 0;
 }

 Reset(ref v1);

Now, you're passing the same storage location in memory of the vector, not a copy of it (v1 and v, are two names for the same thing - same storage location).

But with extension methods, you can't pass by reference (see why). A simple solution is to return the vector again, so:

 public static Vector2 RemoveSmallestComponent(this Vector2 vector)
 {
     if (Mathf.Abs(vector.x) > Mathf.Abs(vector.y)) {
         vector.y = 0;
     }
     else {
         vector.x = 0;
     }
     return vector;
 }

And calling it like:

 Vector2 v = new (1, 2);
 v = v.RemoveSmallestComponent();


Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AntLewis · Dec 15, 2013 at 03:03 PM 1
Share

Fantastic explanation - thanks so much for taking the time!

avatar image vexe · Dec 15, 2013 at 03:06 PM 2
Share

Sure no problem. I'd take a look at this eye-opener from Jon Skeet about value-types vs reference types, and passing byvalue vs byreference. Amazing resource http://www.yoda.arachsys.com/csharp/parameters.html

avatar image Bunny83 · Dec 15, 2013 at 03:37 PM 0
Share

@vexe: Yes it's a great link, but a bit long-winded. But yes, it's a quite common belief, even under experienced programmers, that reference types are "passed by reference", which is simply not true ;)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How can I write and use extension methods in JS? 2 Answers

Texture2D Extension: Texture Still Null After Calling It 1 Answer

Checking if variable is nullable type? 3 Answers

Is it possible to RPC a C# extension method? 1 Answer

Ambiguous reference issue on extension methods 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges