How to get the object references in Vb.net or c#?

Asked

Viewed 168 times

1

I have the code to follow:

Dim objeto1 as new ClasseTal
Dim objeto2 as new SubClasse
Dim objeto3 as new SubClasse

objeto2.Prop1 = objeto1

objeto3.Prop1 = objeto1

that is, I want to count the reference number of the objeto1, in this case it would have to be 2, because it is in the objeto2 and in the objeto3.

  • The CLR does not maintain larger reference counts, so there is no reference count to be obtained. The garbage collector only cares if an object has zero references or at least one reference. https://blogs.msdn.microsoft.com/oldnewthing/20100811-00/? p=13173/

  • Maybe you can create some variable, some static field that counts each time the class is instantiated.

  • Perhaps the simplest way to solve the question would be to place a static (global access) counter that would be incremented in the class constructor. Basically, whenever the class was instantiated the counter increased.

1 answer

1

As far as I know. NET does not inform you the number of references that an object has programmatically, since it is the function of GC to manage the references.
Searching a little I discovered this topic: C# - Get number of References to Object
In it a user says that the counting of references can be dangerous because there can be circular reference cases.

But you can also build a "Manager" that counts the amount of references using the Weakreference and a dictionary.
Follow a basic example to get a notion. (There may be logic error)

using System;
using System.Collections.Generic;
using System.Linq;

namespace HelperStack
{
    public static class ContadorHelper
    {

        /*
         * var objeto1 as new ClasseTal
         * var objeto2 as new SubClasse
         * var objeto3 as new SubClasse
         *
         * objeto2.Prop1 = objeto1.ObterReferencia()
         *
         * objeto3.Prop1 = objeto1.ObterReferencia()
         * Console.log(objeto1.ObterContador())
         */
        private static Dictionary<int, Dictionary<WeakReference, int>> Referencias { get; set; } = new Dictionary<int, Dictionary<WeakReference, int>>();
        /// <summary>
        /// Use esta função toda vez que quiser usar a referencia do objeto em outro local
        /// </summary>
        /// <param name="obj">Objeto qualquer.</param>
        /// <returns></returns>
        public static object ObterReferencia(this object obj)
        {
            AtualizarLista();

            if (Referencias.Count(x => x.Key == obj.GetHashCode()) > 0)
            {
                var aux = Referencias[obj.GetHashCode()].FirstOrDefault();
                if (aux.Equals(default(KeyValuePair<WeakReference, int>)))
                {
                    //Retorna uma unica referencia
                    Referencias[obj.GetHashCode()].Add(new WeakReference(obj), 1);
                    return obj;
                }
                else
                {
                    Referencias[obj.GetHashCode()][aux.Key] = aux.Value + 1;
                    //Retorna uma referencia do objeto
                    return aux.Key.Target;
                }
            }
            else
            {
                //Cria uma nova estrutura
                Referencias.Add(obj.GetHashCode(), new Dictionary<WeakReference, int>());
                Referencias[obj.GetHashCode()].Add(new WeakReference(obj), 1);
                return obj;
            }
        }
        public static int ObterContador(this object obj)
        {
            AtualizarLista();

            if (Referencias.Count(x => x.Key == obj.GetHashCode()) > 0)
            {
                //Obtem a quantodade 
                return Referencias[obj.GetHashCode()].First().Value;
            }
            else
            {
                //Caso não exista referencia do objeto
                return -1;
            }
        }
        private static void AtualizarLista()
        {
            List<int> remover = new List<int>();
            foreach (var objRef in Referencias)
            {
                //Verifica se o GC coletou o objeto
                if (objRef.Value.First().Key.IsAlive)
                {
                    remover.Add(objRef.Key);
                }
            }

            foreach (var keys in remover)
            {
                Referencias.Remove(keys);
            }
        }
    }
}

Browser other questions tagged

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