Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

131
Views
Is there a way to iterate through list of generic values in Unity/c#?

Is it possible to iterate through a several generic instances and do something with them?

public class Dynamic<T>
{
    public T value;
    public T defaultVal;

    public void SetDefaultValue()
    {
        value = defaultVal;
    }
}

Is it even possible to make it look something like this:

List<Dynamic<T>> dynamics = new List<Dynamics<T>>();

dynamics.Add(new Dynamic<float>());
dynamics.Add(new Dynamic<Vector2>());
///...

foreach (var item in dynamics)
{
    item.SetDefaultValue();
}

And yeah, its probably useless at all since I have to manually insert these values in that list, but I really want to know if its even possible.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

With the data model you have, in c# 2.0 there is no way to do what you want other than by declaring dynamics as a List<object> and using reflection:

List<object> dynamics = new List<object>();

dynamics.Add(new Dynamic<float>());
dynamics.Add(new Dynamic<Vector2>());

foreach (var item in dynamics)
{
    item.GetType().GetMethod("SetDefaultValue").Invoke(item, null);
}

Not really recommended, since the performance will be poor, and you lose compile-time checking for correctness.

Instead, consider introducing a non-generic interface that allows accessing required members of Dynamic<T> in a non-generic manner:

public interface IDynamic
{
    // Provide read-only access to the Value and DefaultValue as objects:
    object Value { get; }
    object DefaultValue { get; } 
    // Set the value to the default value:
    void SetDefaultValue();
}

public class Dynamic<T> : IDynamic
{
    public T value;
    public T defaultVal;

    public void SetDefaultValue()
    {
        value = defaultVal;
    }

    // Use explicit interface implementation because we don't want people to use the non-generic properties when working directly with a specific Dynamic<T>:
    object IDynamic.Value { get { return value; } } // Note that if T is a struct the value will get boxed
    object IDynamic.DefaultValue { get { return defaultVal; } } // Note that if T is a struct the value will get boxed
}

Now you will be able to do:

List<IDynamic> dynamics = new List<IDynamic>();

dynamics.Add(new Dynamic<float>());
dynamics.Add(new Dynamic<Vector2>());

foreach (var item in dynamics)
{
    item.SetDefaultValue();
}
over 4 years ago · Santiago Trujillo Report

0

Extending dbc's answer, to have the properties of your class stored in a list to change them at once and by reference you need to wrap them into a class, for this case Dynamic<whatever>, because if you have primitive/value types, those will be copied into the list, and even the property values are changed looping through the list you would be changing the list copies and not the class properties themselves. Like so:

using System;
using System.Collections.Generic;
using UnityEngine;

public class GenericTrial2 : MonoBehaviour {
    Dynamic<float> vertical = new Dynamic<float> { value = 17, defaultVal = 1 };
    Dynamic<Vector2> run = new Dynamic<Vector2> { value = new Vector2(17, 17), defaultVal = Vector2.one };
    Dynamic<Quaternion> rotation= new Dynamic<Quaternion> { value = new Quaternion(4,4,4,4), defaultVal = Quaternion.identity };
    List<IDynamic> dynamics;

    private void Start() {
        dynamics = new List<IDynamic>();
        dynamics.Add(vertical);
        dynamics.Add(run);
        dynamics.Add(rotation);
        dynamics.ForEach(prop => { Debug.Log(prop.Value.ToString()); });
        Debug.Log($"initValues: vertical: {vertical.value.ToString()}, " +
            $"run: {run.value.ToString()}, rot: {rotation.value.ToString()} ");
    }

    void resetProps() {
        foreach (var item in dynamics) {
            item.SetDefaultValue();
        }
        dynamics.ForEach(prop => { Debug.Log(prop.Value.ToString()); });
    }

    private void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            resetProps();
            Debug.Log($"after reset: vertical: {vertical.value.ToString()}, " +
                $"run: {run.value.ToString()}, rot: {rotation.value.ToString()} ");
        }
    }
}
public interface IDynamic {
    // Provide read-only access to the Value and DefaultValue as objects:
    object Value { get; }
    object DefaultValue { get; }
    // Set the value to the default value:
    void SetDefaultValue();
}

public class Dynamic<T> : IDynamic {
    public T value;
    public T defaultVal;

    public void SetDefaultValue() {
        value = defaultVal;
    }

    // Use explicit interface implementation because we don't want people to use the non-generic properties when working directly with a specific Dynamic<T>:
    object IDynamic.Value { get { return value; } } // Note that if T is a struct the value will get boxed
    object IDynamic.DefaultValue { get { return defaultVal; } } // Note that if T is a struct the value will get boxed
}

Output:

initValues: vertical: 17, run: (17.0, 17.0), rot: (4.0, 4.0, 4.0, 4.0)   
after reset: vertical: 1, run: (1.0, 1.0), rot: (0.0, 0.0, 0.0, 1.0) 
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!