Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

125
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda