How to pass a value to a list and make it static?

Asked

Viewed 53 times

0

I have a list of objects that I am filling it in as follows:

var props = type.GetRuntimeProperties();

var obj = new T();

for (int i = 0; i < readerCache.Count; i++)
{
    var prop = props.Single(x => x.GetColumnName().ToLower() == readerCache.ElementAt(i).Item1.ToLower());

    if (prop.GetCustomAttribute<Column>().Type == ColumnType.FK)
    {
        var method = typeof(SelectExtension).GetMethod("SelectSingle");

        var generic = method.MakeGenericMethod(prop.PropertyType);

        prop.SetValue(obj, generic.Invoke(null, new object[] { dBManager, $"WHERE id = '{readerCache.ElementAt(i).Item2}'" }));
    }
    else
    {
        prop.SetValue(obj, readerCache.ElementAt(i).Item2);
    }

    if ((i + 1) % props.Count() == 0)
    {
        objList.Add(obj);
    }
}

When I am debugging, the objects are being filled in correctly, but when the list finishes being filled in, all the elements are equal.

My suspicion is that it is passing the object by reference, and not by value.

Why does this happen? How to fix?

  • You shouldn’t be declaring obj inside the loop?

  • You couldn’t, because obj is only complete after you’ve been through the loop a few times. Doing it the way you said it would instantiate it all the time.

  • Do you have any field that differs between all objects? If yes just do a check

1 answer

0

A list of reference types is nothing more than a list of references. This means that each position in the list keeps a reference to the object inserted there.

Why does this happen?

var obj = new T();

for (int i = 0; i < readerCache.Count; i++)
{
    // Operações que possivelmente mudam a estrutura de 'obj' a cada iteração
    ...
    // Adição da referência de 'obj'
    objList.Add(obj);
}

For more than the structure of the object obj change inside the repeat loop, the reference remains the same. Running objList.Add(obj) you are always adding the reference of the initial object to the list, resulting in a list with multiple references of the same object (i.e., all elements are equal).

How to fix?

  1. Declare obj within the loop. This ensures that each object has a different address in memory and therefore different references will be added to the object list.
  2. If the first option is not possible, I suggest you add to the list of objects a clone of your object.

Creating a clone of an object in C# can be problematic. One of the simplest solutions is by serialization and deserialization. Using the framework Newtonsoft Json.NET, you can do something like this:

objList.Add(JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj)));

If you want, you can implement a custom extension method

public static T Clone<T>(this T source)
{
   return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}

and then use it

objList.Add(obj.Clone());
  • I was curious if there was another way to this question, your answer confirms what I thought. If the code were mine, I would restructure to be able to declare the object inside the loop.

  • I did it the way you said it, but the problem is that the subobjects are coming null -> https://imgur.com/a/XOTC3

Browser other questions tagged

You are not signed in. Login or sign up in order to post.