# TypeHash

> Produces a stable type hash for a Type based on its layout in memory and how that memory should be interpreted.

## Definition

* **Type:** Class
* **Namespace:** [Unity.Entities](/engine/7000.0/script-reference/unity/entities.md)
* **Assembly:** UnityEngine.EntitiesModule

```csharp
public class TypeHash
```

## Remarks

This hash is NOT expected to remain the same across versions.

You can rename field members and this hash isn't affected. However, if a field's type changes, this hash changes, because the interpretation of the underlying memory will have contextually changed.

The purpose of the stable type hash is to provide a version linking serialized component data to its runtime representation.

As such, the type hash has a few requirements:

* **R0:** TypeHashes apply only to types that Unity.Entities serializes. The internals of a UnityEngine.Object reference contained in a component mustn't have an effect on the type hash. You can safely change the internals of the UnityEngine.Object reference because they're serialized outside of Unity.Entities.

* **R1:** Types with the same data layout but are different types should have different hashes.

* **R2:** If a type's data layout changes, so should the type hash. This includes:

* A nested field's data layout changes (for example, a new member added)

* FieldOffsets, explicit size, or pack alignment are changed

* Different types of the same width swap places (for example if a uint swaps with an int)

* **Note:** Unity can't detect if fields of the same type swap (for example, mInt1 swaps with mInt2) This is a semantic difference which you should increase your component \[TypeVersion(1)] attribute. You shouldn't try to hash field names to handle this, because you can't control all field names. Also, field names have no effect serialization and doesn't affect hashes.

  * **R3:** You should version the hash in case the semantics of a type change, but the data layout is unchanged

  * **R4:** DOTS Runtime relies on hashes generated from the Editor (used in serialized data) and hashes generated during compilation. These hashes must match. This rule exists because of the following:

* Tiny swapa out assemblies for 'tiny' versions, which means you should avoid any hashing using the AssemblyName or handle it specially for the known swapped assemblies.

* This means you should avoid Type.AssemblyQualifiedName in hashes, but as well, closed-form generic types include the assembly qualified name for GenericArguments in Type.FullName which causes issues. For example, @@typeof(ComponentWithGeneric.GenericField).FullName == Unity.Entities.ComponentWithGeneric.GenericField@@10, Culture=neutral, PublicKeyToken=b77a5c561934e089\`

* System.Reflection and Mono.Cecil provide different Type names (they use a different format). Generating hashes from System.Reflection to match hashes using Mono.Cecil must account for this difference.

## Static Methods

| Method                                                                                                        | Description                                       |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| [CalculateMemoryOrdering](/engine/7000.0/script-reference/unity/entities/typehash/calculatememoryordering.md) | Calculates a MemoryOrdering for the input type.   |
| [CalculateStableTypeHash](/engine/7000.0/script-reference/unity/entities/typehash/calculatestabletypehash.md) | Calculates a stable type hash for the input type. |
| [CombineFNV1A64](/engine/7000.0/script-reference/unity/entities/typehash/combinefnv1a64.md)                   | Combines a FNV1A64 hash with a value.             |
| [FNV1A64](/engine/7000.0/script-reference/unity/entities/typehash/fnv1a64.md)                                 | Generates a FNV1A64 hash.                         |
