Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey guys,
I've done a little bit of searching for this but I'm either not finding the answer or simly not understanding it.

Several instance of a particular class are use in my application. All instances have A String property [Title] that needs to remain unique. To do this, I've decided to add a number Property
to the class and increment it when a title is set to the same value as another instance of this
Class.
In order to that, I need to count every instance of the class that contains the same value for [title_]

Please examine the fallowing code under HELP


Ultimately I'm planning on listing all of these instances for the user the choose from.

I know there is a way to gather open forms in the application under System.windows.application.Openforms And then check form type using gettype()but I'm not sure
if it's possible to do the same with class instances.

The Class' GetTitleValue() Procedure will be called to check for matching strings.

Thank you for all feedback.

VB
Public Class MyClass

 Private Title_ As String = "Sample List"
 Private SimmilarlyNamedInstanceNumber as integer = 0

    Public Property Title() As String
        Set(NewTitle As String)
            Dim cnt As Integer = 1


               '-------------  HELP  ------------------
               'Need to count the number of instances of this class
               'That have the same [Title] Value (ignoring Casing)
               'and set SimmilarlyNamedInstanceNumber as that value + 1
               '------------ End Help ------------------


            Title_ = NewTitle
        End Set
        Get
           'Return The Name of this Instance and Unique Number for the name
            Return Title_ & " " & SimmilarlyNamedInstanceNumber.ToString
        End Get

   'Used to return the un-altered title value of the class in order to check for duplicates.
   Public Function GetTitleValue() as string
      Return Title_
   End Sub
end class
Posted

1 solution

It is simpler than that. You need a static field as counter, and be sure to make all constructors increment it, and the destructor decrement it (be aware of the garbage collector) - but this later part is not needed in you case as I see.
The c# template is the follwoing:
C#
class MyClass
{
    static int counter = 0;

    public MyClass()
    {
        Interlocked.Increment(ref counter);
    }

    public ~MyClass()
    {
        Interlocked.Decrement(ref counter);
    }
}

The VB.NET version would be:
VB
Class [MyClass]
    Shared counter As Integer = 0

    Public Sub New()
        Interlocked.Increment(counter)
    End Sub

    Protected Overrides Sub Finalize()
        Try
            Interlocked.Decrement(counter)
        Finally
            MyBase.Finalize()
        End Try
    End Sub
End Class


The list part is a little bit more complicated because of the same garbage collector (source[^])
C#
public class MyClass
{
    private static List<WeakReference> instances = new List<WeakReference>();

    public MyClass()
    {
         instances.Add(new WeakReference(this));
    }

    public static IList<MyClass> GetInstances()
    {
        List<MyClass> realInstances = new List<MyClass>();
        List<WeakReference> toDelete = new List<WeakReference>();

        foreach(WeakReference reference in instances)
        {
            if(reference.IsAlive)
            {
                realInstances.Add((MyClass)reference.Target);
            }
            else
            {
                toDelete.Add(reference);
            }
        }

        foreach(WeakReference reference in toDelete) instances.Remove(reference);

        return realInstances;
    }
}

But can be simpler if the usage of the list let's you make it simpler.

[Update: working exampe]
C#
using System;
using System.Collections.Generic;
using System.Linq;

namespace listed
{
	public class MyClass
	{
		#region instance collection
		private static List<WeakReference> instances = new List<WeakReference>();
		
		public IList<WeakReference> Instances 
		{
			get 
			{
				return instances.AsReadOnly();
			}
		}
	 
	    public static IList<MyClass> GetInstances()
	    {
	        List<MyClass> realInstances = new List<MyClass>();
	        List<WeakReference> toDelete = new List<WeakReference>();
	 
	        foreach(WeakReference reference in instances)
	        {
	            if(reference.IsAlive)
	            {
	                realInstances.Add((MyClass)reference.Target);
	            }
	            else
	            {
	                toDelete.Add(reference);
	            }
	        }
	 
	        foreach(WeakReference reference in toDelete) instances.Remove(reference);
	 
	        return realInstances;
	    }
	    #endregion
	    
	    #region instance specific
	    public int instanceIndex { get; private set; }
	    public string baseTitle { get; private set; }
	    
	    public string Title 
	    {
	    	get 
	    	{
	    		return string.Format("{0}{1}", this.baseTitle, this.instanceIndex);
	    	}
	    }
	    
	    public MyClass(string title) 
	    {
	        this.baseTitle = title;
	        this.instanceIndex = instances.Count(x => ((MyClass)x.Target).baseTitle == title) + 1;
	        	
	    	instances.Add(new WeakReference(this));
	    }
	    #endregion
	}
	
	class Program
	{
		public static void Main(string[] args)
		{
			var o1 = new MyClass("List");
			Console.WriteLine(o1.Title);
			
			var o2 = new MyClass("SampleList");
			Console.WriteLine(o2.Title);
			
			var o3 = new MyClass("List");
			Console.WriteLine(o3.Title);
			
			var o4 = new MyClass("SampleList");
			Console.WriteLine(o4.Title);
			
			var o5 = new MyClass("List");
			Console.WriteLine(o5.Title);
			
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}
}
 
Share this answer
 
v2
Comments
Mr.TMG 7-Sep-13 18:42pm    
I'm not a c# user but in the LIST Example that you provide, it looks like you're adding the instance to a list of CLASS(instaces) as it is created. Is this list contained inside of every instance of the class? If so, is it the same list in every instance of the class?

I'm having some trouble in fully comprehending whats going on here.

Added note: I will need be able to loop through the list of instances so that I can display them to the user for selecting which instance of the class to add items to. Can this be done as;
Dim x as new MyClass
for each y as myclass in in x.instance
SomeDisplayBoxClassInstanceForUser.AddMyClassInstance(y)
next

Is there some way -- Outside of the MyClass to collect a list of instance?

As far as cycling through each instance inside the class at the time of changing the title; I only want to increment the counter based on matching titles.
Ecample: if I have three instances open and they are all labeled "List"
The user would see "List 1" "List 2" "List 3"
If I had another instance Labeled "SampleList"
The user would see "List 1" "List 2" "List 3" "SampleList 1"


Thank you for the response.
Zoltán Zörgő 8-Sep-13 15:15pm    
Too much question for one post :)
Ok, let's start with the list: a static field is used for that. It's value can be accessed from any instance - or from outside if you make it public. Thus you could iterate even from an other class.
Of course, you could collect them in a separate class but this is a cleaner approach.

If you want to get the next available suffix for the title, you could store both the index and the base title, thus you could simply use LINQ to get the next available index for it. And you could simply make a property to get the concatenated title.
Mr.TMG 8-Sep-13 15:41pm    
So yesterday I was up for about 20 hour working with this program. Now that I've had some sleep, everything just makes so much more since. Like SHARED: "A programming element that is associated with all instances of the class." Sorry bud, you were a huge help with the solution post and I continued to bombard you with more questions.

Thank you much for responding.
Zoltán Zörgő 8-Sep-13 15:40pm    
See my update above. Run the code as console application.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900