Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
This question was closed Jan 20, 2017 at 01:09 AM by MrFloat for the following reason:

The documentation has been updated so I'm closing this question as outdated

avatar image
2
Question by MrFloat · Sep 21, 2016 at 02:16 PM · scripting problembug

ISerializationCallbackReceiver not working for structs?

I'm trying to create a simple struct that wraps a string and a cached hash code value for when I need to use a string for dictionary lookups a lot. But I'm having problems using ISerializationCallbackReceiver.

https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.OnBeforeSerialize.html states that
"The interface can be used on MonoBehaviours like in the example, but it can also be used on custom classes and structs"

a simple example of

 HashedString test1 = new HashedString("Text1");
 string test2 = JsonUtility.ToJson(test1);
 HashedString test3 = JsonUtility.FromJson<HashedString>(test2);

Does not work for me if HashedString is a struct but changing it into a class makes this run as intended. Is the documentation false? am I using ISerializationCallbackReceiver in a wrong way? or is this a bug on newer releases as I just got the new Unity 5.4.1 today.
I would very much like to use a struct for this

Here is my HashedString code:

 //This define option forces HashedString class to only consider hashes when comparing for equality
 //#define HASHED_STRING_FORCE_HASH_EQUALS
 
 using System;
 using System.Runtime.Serialization;
 using UnityEngine;
 
 namespace Common.Text
 {
     /// <summary>
     /// Class to wrap a string with its cached hash value,
     /// as default string implementation calculates it on demand.
     /// This is useful for cases where string hashes are often requested.
     /// </summary>
     /// <seealso cref="System.IEquatable{Common.Text.HashedString}" />
     /// <seealso cref="System.IComparable{Common.Text.HashedString}" />
     /// <seealso cref="System.IComparable" />
     [Serializable]
     public struct HashedString : IEquatable<HashedString>, IComparable<HashedString>, IComparable, ISerializationCallbackReceiver
     {
         /// <summary>
         /// The string text.
         /// </summary>
         [SerializeField]
         private string m_Text;
 
         /// <summary>
         /// The cached string hash value.
         /// </summary>
         [NonSerialized]
         private int m_Hash;
 
         /// <summary>
         /// The string text.
         /// </summary>
         public string Text { get { return m_Text; } }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="HashedString"/> struct.
         /// </summary>
         /// <param name="i_Text">The string text.</param>
         public HashedString(string i_Text)
         {
             m_Text = i_Text;
             m_Hash = i_Text.GetHashCode();
         }
 
         /// <summary>
         /// Performs an implicit conversion from <see cref="HashedString"/> to <see cref="System.String"/>.
         /// </summary>
         /// <param name="i_Obj">The object.</param>
         /// <returns>
         /// The text string of <see cref="HashedString"/>.
         /// </returns>
         public static implicit operator string(HashedString i_Obj)
         {
             return i_Obj.m_Text;
         }
 
         [OnDeserialized]
         private void InitValuesOnDeserialized(StreamingContext context)
         {
             m_Hash = m_Text.GetHashCode();
         }
 
         /// <summary>
         /// Performs an implicit conversion from <see cref="System.String"/> to <see cref="HashedString"/>.
         /// </summary>
         /// <param name="i_Text">The <see cref="HashedString"/> text.</param>
         /// <returns>
         /// The <see cref="HashedString"/> representation of the string.
         /// </returns>
         public static implicit operator HashedString(string i_Text)
         {
             return new HashedString(i_Text);
         }
 
         /// <summary>
         /// Implements the operator ==.
         /// </summary>
         /// <param name="i_ObjA">The object a.</param>
         /// <param name="i_ObjB">The object b.</param>
         /// <returns>
         /// The equality result.
         /// </returns>
         public static bool operator ==(HashedString i_ObjA, HashedString i_ObjB)
         {
 #if UNITY_EDITOR
             if ((i_ObjA.m_Text == i_ObjB.m_Text) != (i_ObjA.m_Hash == i_ObjB.m_Hash))
             {
 #if HASHED_STRING_FORCE_HASH_EQUALS
                 Debug.LogErrorFormat(
 #else
                 Debug.LogWarningFormat(
 #endif
                     "Incorrect IntelligentTextId early match due to a hash clash ({0} == {1})", i_ObjA.m_Text, i_ObjB.m_Text);
             }
 #endif
 
 #if HASHED_STRING_FORCE_HASH_EQUALS
             return i_ObjA.Hash == i_ObjB.Hash;
 #else
             if (i_ObjA.m_Hash == i_ObjB.m_Hash)
             {
                 return i_ObjA.m_Text == i_ObjB.m_Text;
             }
             return false;
 #endif
         }
 
         /// <summary>
         /// Implements the operator !=.
         /// </summary>
         /// <param name="i_ObjA">The object a.</param>
         /// <param name="i_ObjB">The object b.</param>
         /// <returns>
         /// The result of the operator.
         /// </returns>
         public static bool operator !=(HashedString i_ObjA, HashedString i_ObjB)
         {
             return !(i_ObjA == i_ObjB);
         }
 
         /// <summary>
         /// Returns a hash code for this instance.
         /// </summary>
         /// <returns>
         /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
         /// </returns>
         public override int GetHashCode()
         {
             return m_Hash;
         }
 
         /// <summary>
         /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
         /// </summary>
         /// <param name="i_Obj">The <see cref="System.Object" /> to compare with this instance.</param>
         /// <returns>
         ///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
         /// </returns>
         public override bool Equals(object i_Obj)
         {
             HashedString hashedText = (HashedString)i_Obj;
             return this == hashedText;
         }
 
         /// <summary>
         /// Determines whether the specified <see cref="Common.Text.HashedString" />, is equal to this instance.
         /// </summary>
         /// <param name="i_Obj">The <see cref="Common.Text.HashedString" /> to compare with this instance.</param>
         /// <returns>
         ///   <c>true</c> if the specified <see cref="Common.Text.HashedString" /> is equal to this instance; otherwise, <c>false</c>.
         /// </returns>
         public bool Equals(HashedString i_Other)
         {
             return this == i_Other;
         }
 
         /// <summary>
         /// Compares the specified <see cref="System.Object" /> to this instance.
         /// </summary>
         /// <param name="i_Obj">The object.</param>
         /// <returns>
         /// -1 if this instance is less than the given object, 1 if greater and 0 otherwisse.
         /// </returns>
         public int CompareTo(object i_Obj)
         {
             HashedString hashedText = (HashedString)i_Obj;
             return m_Text.CompareTo(hashedText.m_Text);
         }
 
         /// <summary>
         /// Compares the specified <see cref="Common.Text.HashedString" /> to this instance.
         /// </summary>
         /// <param name="i_Other">The object.</param>
         /// <returns>
         /// -1 if this instance is less than the given object, 1 if greater and 0 otherwisse.
         /// </returns>
         public int CompareTo(HashedString i_Other)
         {
             return m_Text.CompareTo(i_Other.m_Text);
         }
 
         public void OnBeforeSerialize()
         { }
 
         public void OnAfterDeserialize()
         {
             m_Hash = m_Text.GetHashCode();
         }
     }
 }
 
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

  • Sort: 
avatar image
1
Best Answer

Answer by Novack · Oct 26, 2016 at 11:23 PM

The documentation seems to be contradictory. The same documentation page reads:

The interface can be used on MonoBehaviours like in the example, but it can also be used on custom classes and structs.

And:

Currently only classes will receive the callbacks. Structs will not.

This has been patched on the Unity beta docs, and reflects what you are experiencing. At least for now, it does not work on structs.

Comment
Add comment · 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

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Prefab is spawned two times in a row 0 Answers

LineRenderer SetPositions gives a SetPosition index out of bounds 0 Answers

Instantiated UI elements not rendering on canvas 1 Answer

Why do placing a preprocessor directive inside another causes my script to lose proper indentation? 1 Answer

I keep getting the "A namespace does not directly contain members such as fields or methods" error. Can someone please tell me how to fix this error? 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