C#struct像Reference一样处理

时间:2015-10-12 12:16:35

标签: c#

我有一个名为KinectBody的结构体,我将一个名为BodyContributor的类中的此类对象分配给一个名为KinectSystemComponent的类中的字段。现在每次BodyContributor中的字段发生变化时,我的KinectSystemComponent中的字段也会像引用类型一样发生变化。这是怎么发生的。以下是相关课程:

using System.Collections.Generic;

namespace Alpaca.Systems.Kinect
{
     public class KinectSystemComponent : KinectComponent, Alpaca.Systems.Events.IEventHandler<UserTrackingEvent>
     {
          private static Dictionary<ulong, KinectBody> assignedBodies = new Dictionary<ulong, KinectBody>();
          BodyContributor contributor;
          public static bool useSystemComponents = true;

          public static bool IsBodyAlreadyAssigned(KinectBody body)
          {
               return assignedBodies.ContainsKey(body.trackingID);
          }

          public override void Initialize()
          {
               contributor = BodySource.Instance.contributor;
               this.ComponentType = ComponentType.SystemComponent;
          }
          public override void OnUpdate()
          {
               //if(useSystemComponents)
               //{
               //     if(!Body.isTracked)
               //     {
               //          KinectBody[] bodies = contributor.GetBodies();

               //          for(int i = 0; i < bodies.Length; i++)
               //          {
               //               KinectBody currentBody = bodies[i];
               //               if(currentBody.isTracked)
               //               {
               //                    if(!IsBodyAlreadyAssigned(currentBody))
               //                    {
               //                         this.Body = currentBody;
               //                    }
               //               }
               //          }
               //     }
               //     else
               //     {
               //          Body = contributor.GetBodyByID(Body.trackingID);
               //     }
               //}

               //else if(Body.isTracked)
               //{
               //     Body = new KinectBody();
               //}
          }

          public void HandleEvent(UserTrackingEvent @event)
          {
               Body = contributor.GetBodyByID(@event.id);
          }
     }
}

using System;
using Alpaca.Systems;

namespace Alpaca.Systems.Kinect
{
     public abstract class KinectComponent : AlpacaComponent
     {
          private KinectBody body;
          public KinectBody Body
          {
               get
               {
                    return body;
               }
               protected set
               {
                    body = value;
               }
          }
     }
}

using System.Collections.Generic;
using UnityEngine;
using Windows.Kinect;
using Alpaca.Utility;

namespace Alpaca.Systems.Kinect
{
     public struct KinectBody
     {
          public Dictionary<JointType, KinectJoint> joints;
          Dictionary<JointType, Windows.Kinect.Joint> rawJoints;
          public bool isTracked;
          public ulong trackingID;
          public Vector3 position;
          public Vector3 hipsDirection;
          public Vector3 shouldersDirection;
          public float bodyTurnAngle;
          public Vector3 leftArmDirection;
          public Vector3 rightArmDirection;

          public void Init()
          {
               joints = new Dictionary<JointType, KinectJoint>(25, new JointTypeComparer());
          }

          public void RefineBody(Body body)
          {
               this.rawJoints = body.Joints;

               for(int i = 0; i < 25; i++)
               {
                    joints[KinectHelper.GetJointAtIndex(i)] = new KinectJoint(rawJoints[KinectHelper.GetJointAtIndex(i)]);
               }

               position = joints[JointType.SpineMid].position;
               isTracked = body.IsTracked;
               trackingID = body.TrackingId;
               hipsDirection = Vector3.zero;
               shouldersDirection = Vector3.zero;
               bodyTurnAngle = 0;
               leftArmDirection = Vector3.zero;
               rightArmDirection = Vector3.zero;
          }

          public void ModifyJoint(JointType type, KinectJoint joint)
          {
               joints[type] = joint;
          }
     }

     public class KinectBodyComparer : IEqualityComparer<KinectBody>
     {
          bool System.Collections.Generic.IEqualityComparer<KinectBody>.Equals(KinectBody x, KinectBody y)
          {
               return x.trackingID == y.trackingID;
          }
          int System.Collections.Generic.IEqualityComparer<KinectBody>.GetHashCode(KinectBody obj)
          {
               return unchecked((int) (obj.trackingID % 1000));
          }
     }
}

namespace Alpaca.Systems.Kinect
{
     public abstract class BodyContributor
     {
          protected KinectBody[] bodies = new KinectBody[6];
          private BodyRefiner refiner;
          protected KinectBody emptyBody;

          public BodyContributor(BodyRefiner refiner)
          {
               this.refiner = refiner;
               emptyBody = new KinectBody();
          }

          public void Update()
          {
               this.bodies = refiner.GetBodies();
               UpdateBodies();
          }

          protected abstract void UpdateBodies();

          public KinectBody GetBodyByID(ulong id)
          {
               for(int i = 0; i < bodies.Length; i++)
               {
                    KinectBody curBody = bodies[i];
                    if(curBody.trackingID == id)
                    {
                         return curBody;
                    }
               }
               return emptyBody;
          }

          public KinectBody[] GetBodies()
          {
               return bodies;
          }
     }
}

1 个答案:

答案 0 :(得分:1)

正如Carsten所指出的那样,KinectComponent是一个类,一个引用类型。

KinectBody可能是值类型,但它包含引用类型(Dictionary s),我怀疑它会导致您不期望的行为。 你的结构也很大且可变,这会打破这些useful design guidelines