In this tip, you will find a useful scenario where Visual Studio's Make Object Id feature could be utilized.
Introduction
I blogged about using Visual Studio's "Make Object Id" feature here for inspecting out of scope objects. In this tip, I will demonstrate another (hopefully) useful scenario where this feature could be utilized.
Background
Let’s say you have hundreds of managed objects on the heap and you need to debug certain parts of the code only when a particular instance out of those objects is referred in that piece of code. Typically, you will put a breakpoint in the method where you want to break. However, if this method is invoked for all those hundreds of managed objects, then this breakpoint will hit so many times, you may feel tired of waiting for your lucky time when method is being hit for instance that you are interested in.
Description
The sample code I am going to show here is very simple but it's good enough to give you a good idea of this use case.
Let's say, we have an Employee
class. Then we have a method LoadEmployees
where we are loading 1000 employees and adding in a list. Please note that I have used Member.GeneratePassword
API just for generating some temporary strings to be used for last and first name of the employee
. Then for each Employee
in that list, we are calling several methods like ProcessSalary
, ProcessRetiremendFund
, etc. that are doing some processing related to various aspects of benefits. For simplicity, I am just printing some text message with employee's id in each of these methods.
class Employee
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public Employee(int id, string last, string first)
{
this.Id = id;
this.LastName = last;
this.FirstName = first;
}
}
class Program
{
static void Main(string[] args)
{
List<employee> <Employees> = new List<Employees><employee>();
LoadEmployees(Employees);
foreach(Employee emp in Employees)
{
ProcessSalary(emp);
ProcessRetirementFund(emp);
ProcessMedicalBenefit(emp);
ProcessDentalBenefit(emp);
ProcessLifeInsurance(emp);
}
Console.WriteLine("Done");
}
static void LoadEmployees(List<employee> Employees)
{
for (int i = 0; i < 1000; i++)
{
Employee emp = new Employee
(i, Membership.GeneratePassword(6, 0), Membership.GeneratePassword(6, 0));
Employees.Add(emp);
}
}
static void ProcessSalary(Employee emp)
{
Console.WriteLine("Salary Processing for employee with id = " + emp.Id);
}
static void ProcessRetirementFund(Employee emp)
{
Console.WriteLine("Retirement funds Processing for employee with id = " + emp.Id);
}
static void ProcessMedicalBenefit(Employee emp)
{
Console.WriteLine("Medical Benefits Processing for employee with id = " + emp.Id);
}
static void ProcessDentalBenefit(Employee emp)
{
Console.WriteLine("Dental Benefits Processing for employee with id = " + emp.Id);
}
static void ProcessLifeInsurance(Employee emp)
{
Console.WriteLine("LifeInsurance Processing for employee with id = " + emp.Id);
}
}
Let's say something is happening wrong in processing related to an employee
with id 775
. Since processing has been implemented in several methods, we are not sure which method is faulty and as a result, we need to debug all the ProcessXXX
methods. However, since these ProcessXXX
methods are called for each of 1000 employees in the list, it will not be an efficient way of debugging by breaking in each of these methods for every single employee. Rather, we can simply add a conditional breakpoint for employee
with id 775
as follows:
This was simple to do because the only criteria we have match is on that object's Id
field. However, this technique becomes tedious when you have to match on multiple fields of object. In that case, you can use another technique that involves two steps. The first step is to use "Make Object ID" feature on the class instance. This can be done by hovering the mouse over on the emp
object of interest ( meaning when its id = 775
). Once the data-tip show up, right click on the variable name and you will get an option for "Make Object ID" as shown in the figure below.
Once you select "Make Object ID" option from context menu, this particular object will be available to be referred as 1#. If you used this option for any other variables, then you will see the number 1 (in 1#) getting incremented. At this point, you will also notice that 1# will be added in object value under Locals
window as shown below:
Now that this variable is available to be referred as 1#, we can use this shortcut in our conditional breakpoints. All the methods where you want to break, you can add a conditional breakpoint using this shortcut as follows rather referencing all the fields that you want to match on.
I hope you will find this tip helpful.
History
- 3rd June, 2012: First version added