# Generic

> Represents an array, list, struct or class.

## Definition

* **Type:** Field
* **Namespace:** [UnityEditor](/engine/6000.0/script-reference/unityeditor.md)
* **Assembly:** UnityEditor

```csharp
Generic = -1
```

### Remarks

The Generic type is used for compound types that are serialized in-line:

* Arrays and lists.

* Structs that are user defined (e.g. not a built in Unity type).

* Classes that are serialized 'by value' (e.g. referenced without the [SerializeReference](/engine/6000.0/script-reference/unityengine/serializereference.md) attribute).

* Certain built in Unity structs, when they do not have dedicated SerializedPropertyType enum value. For example [RectOffset](/engine/6000.0/script-reference/unityengine/rectoffset.md) is Generic, but [Vector3](/engine/6000.0/script-reference/unityengine/vector3.md) is [SerializedPropertyType.Vector3](/engine/6000.0/script-reference/unityeditor/serializedpropertytype/vector3.md).

Note: The term Generic, when used as a SerializedProperty type, should not be confused with the unrelated C# feature of Generic classes and methods.

Additional Resources: [SerializedProperty.isArray](/engine/6000.0/script-reference/unityeditor/serializedproperty/isarray.md), [SerializedPropertyType.ManagedReference](/engine/6000.0/script-reference/unityeditor/serializedpropertytype/managedreference.md), [SerializedPropertyType.ObjectReference](/engine/6000.0/script-reference/unityeditor/serializedpropertytype/objectreference.md)

### Examples

```csharp
using System;
using System.Text;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

namespace GenericObjectTypeExample
{
    [Serializable]
    public struct ExampleStruct
    {
        public int m_Field;
    };

    [Serializable]
    public class ExampleClass
    {
        public int m_Field;
    };

    public class GenericTypeExample : ScriptableObject
    {
        // All these fields will be serialized
        public int[] m_ArrayOfInt;
        public List<int> m_ListOfInt;
        public ExampleStruct m_ExampleStruct = new ExampleStruct() { m_Field = 1 };
        public ExampleClass m_ExampleClass = new ExampleClass() { m_Field = 2 };

        [SerializeReference]
        public ExampleClass m_ManagedClass = new ExampleClass() { m_Field = 3 };

        [MenuItem("Example/SerializedPropertyType Generic Example")]
        static void GenericExample()
        {
            var scriptableObject = ScriptableObject.CreateInstance<GenericTypeExample>();
            using (var serializedObject = new SerializedObject(scriptableObject))
            {
                var report = new StringBuilder();

                // Generic
                ReportType(report, serializedObject, "m_ArrayOfInt");
                ReportType(report, serializedObject, "m_ListOfInt");
                ReportType(report, serializedObject, "m_ExampleStruct");
                ReportType(report, serializedObject, "m_ExampleClass");

                // Not Generic
                ReportType(report, serializedObject, "m_ManagedClass");

                Debug.Log(report.ToString());

                AccessGenericValues(serializedObject);
            }
        }

        static void AccessGenericValues(SerializedObject serializedObject)
        {
            // "generic" type struct and objects can be retrieved directly with boxedValue
            ExampleStruct structValues = (ExampleStruct)serializedObject.FindProperty("m_ExampleStruct").boxedValue;

            // Alternatively individual fields can be read
            int fieldInStruct = serializedObject.FindProperty("m_ExampleStruct.m_Field").intValue;

            Debug.Log($"Value of field in struct: {structValues.m_Field}, Value of field direct read: {fieldInStruct}");

            // Similarly boxedValue supports writing to an inline class
            SerializedProperty inlineClass = serializedObject.FindProperty("m_ExampleClass");

            // Serialize new state in a single call
            inlineClass.boxedValue = new ExampleClass() { m_Field = 4 };

            // Individual fields can also be accessed
            Debug.Log($"Value of field in class after write: {inlineClass.FindPropertyRelative("m_Field").intValue}");

            serializedObject.ApplyModifiedProperties();
        }

        static void ReportType(StringBuilder report, SerializedObject serializedObject, string propertyPath)
        {
            var serializedProperty = serializedObject.FindProperty(propertyPath);
            report.AppendLine($"{propertyPath} has type {serializedProperty.propertyType}");
        }
    }
}
```
