Search Unity

Pointers in C#

Discussion in 'Scripting' started by 2dboy, Jul 3, 2015.

  1. 2dboy

    2dboy

    Joined:
    Mar 4, 2015
    Posts:
    2
    Hello, I used a long time С++ and accustomed to use pointers, now i try assign Vector2 null value, but get error "Cannot convert null to `UnityEngine.Vector2' because it is a value type" what is needed the variable type for assign null to Vector2? Maybe in C# have smart pointers like C++ ??
     
  2. 2dboy

    2dboy

    Joined:
    Mar 4, 2015
    Posts:
    2
    I tried slightly rewrite code with bool variable, and get another weird error: Use of possibly unassigned field `x'
    Code (CSharp):
    1. Vector2 lastPoint;
    2. bool first = true;
    3.  
    4. foreach (var point in points) {
    5.  
    6.     if (!first) {
    7.  
    8.         Gizmos.DrawLine(new Vector3(lastPoint.x, lastPoint.y, 0.0f),
    9.                         new Vector3(point.x, point.y, 0.0f));
    10.  
    11.     }
    12.  
    13.     first = false;
    14.     lastPoint = point;
    15.  
    16. }
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    C# doesn't use explicit pointers. Instead a type defines if it's a value type or a reference type.

    Structs are value types
    Classes are references types

    You can create temporary pointers to value types with the 'ref' and 'out' keywords in methods. But these aren't really pointers like you want.

    You can create a class that has a struct as it's sole field, and then the object for that class will be by reference, and if you update it's field, it'll be updated across references to the object housing it. In newer versions of .Net there is a Tuple class that makes doing this super easy:
    https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

    Unfortunately the version of mono that is used doesn't have the tuple class, but it's fairly easy to make:
    https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBase/Tuple.cs



    As for your example code in your second post, why do you need a pointer for this?

    You don't even need that bool if the collection is a list or array.

    Code (csharp):
    1.  
    2. for(int i = 1; i < points.Length; i++)
    3. {
    4.     //nice thing is Unity has implicit conversion for Vector2 to Vector3
    5.     Gizmos.DrawLine(points[i - 1], points[i]);
    6. }
    7.  
     
    Last edited: Jul 3, 2015
    eisenpony likes this.
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Oh... I see why you wanted it to be a pointer.

    You want to be able to say:

    Code (csharp):
    1.  
    2. Vector2* lastPoint = NULL;
    3. foreach(Vector2 point in points)
    4. {
    5.     if(lastPoint != NULL)
    6.     {
    7.         //draw
    8.     }
    9.     lastPoint = point;
    10. }
    11.  
    You can get this behaviour with Nullable<T>:
    https://msdn.microsoft.com/en-us/library/b3h38hb0(v=vs.110).aspx

    It would be written as:

    Code (csharp):
    1.  
    2. Vector2? lastPoint = null;
    3. foreach(var point in points)
    4. {
    5.     if(lastPoint != null)
    6.     {
    7.         //draw
    8.     }
    9.     lastPoint = point;
    10. }
    11.  
    Note the question mark on Vector2, that declares it's nullable. Though really... you have other options, like the one I previously posted.
     
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Forgive a C# baby, but what's the use case here, as in, what task are you trying to accomplish?

    In most cases you can get by without pointers, and you only need to drop to that level if you are squeezing out the last drop of performance from a system.
     
  6. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    cool.

    Code (csharp):
    1. public void Draw(IEnumerable<Vector2> points)
    2. {
    3.   if (points != null && points.Count() > 1)
    4.     DrawRecursive(points.First(), points.Skip(1));
    5. }
    6. private void DrawRecursive(Vector2 point, IEnumerable<Vector2> remainingPoints)
    7. {
    8.   if (remainingPoints.Count() > 0)
    9.   {
    10.     Gizmos.DrawLine(point, remainingPoints.First());
    11.     DrawRecursive(remainingPoints.First(), remainingPoints.Skip(1));
    12.   }
    13. }
    Sorry.. Couldn't help myself! :(
     
    Last edited: Jul 4, 2015
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    As it's an editor script, I usually don't concern myself with garbage and efficiency.

    But it should be pointed out that too much linq can cause a lot of garbage in the gc cycle. As well as recursive calls like that, in large collections, can result in stack overflows.

    I love recursion for the elegancy of it. But in the real world, it can often lead to many issues.