Virtual Method logic not working C# .NET 4.0 - c#

I'm working through an example in the bookPro C# and the .NET Platform and I'm making a mistake somewhere that I can't see. The program compiles and runs, but the Manager object in this example isn't having the right value of 'StockOptions' returned. In an effort of concision, I'm going to try to only post the relevant code because this example is all about class hierarchies and there's like six different classes. The virtual method GiveBonus in the Employee class isn't being correctly overridden in the Manager class.
class Manager : Employee
{
private int numberOfOpts;
//the properties are inherited from Employee
public int StockOptions { get; set; }
//***METHODS*** this is returns the StockOptions amount as it is in the
// constructor, there's no logic being applied
public override void GiveBonus(float amount)
{
base.GiveBonus(amount);
Random r = new Random();
numberOfOpts += r.Next(500);
}
public override void DisplayStats()
{
base.DisplayStats();
Console.WriteLine("you have {0} stock options", StockOptions);
}
public Manager() { }
public Manager(string fullName, int age, int empID, float currPay,
string ssn, int numbofOpts) : base(fullName, age, empID, currPay, ssn)
{
ID = empID;
Age = age;
Name = fullName;
Pay = currPay;
StockOptions = numbofOpts;
}
}
snippet from my Main() method
Manager chucky = new Manager("chucky", 50, 92, 100000, "333-33-3333", 9000);
chucky.GiveBonus(300);
chucky.DisplayStats();
Console.WriteLine();
I made a mistake while asking the question. What I should have asked is why I have to use
Console.WriteLine("you have {0} stock options", numbOfOpts);
instead of
Console.WriteLine("you have {0} stock options", StockOptions);

It's not meant to add a random number to 9000 - it's meant to give a random number of stock options as well as the "base" pay bonus:
public override void GiveBonus(float amount)
{
base.GiveBonus(amount);
Random r = new Random();
// Note numberOfOpts, not currPay
numberOfOpts += r.Next(500);
}
Unfortunately, as we've got two separate fields - one created by an automatically implemented property - it won't actually update the value of StockOptions... it's not clear whether this is due to your editing, or whether it's a mistake in the book. (There are various other things I dislike about this code, but hey...)

Related

Creating instance of a class with List as a parameter in C#

Hello I am trying to create a bank application with 3 classes-Bank, Account, Mainprogram. In my Main program i have an option for the user to Add a new bank account. In my bank class i have my attributes, constructor and add account method.
class Bank
{
// Attributes
private List<int> accounts { get; set; }
private int number_of_accounts { get; set; }
//Constructor
public Bank(List<int> accounts, int number_of_accounts)
{
this.accounts= accounts;
this.number_of_accounts = number_of_accounts;
}
public void AddNewAccount(int accountNumber)
{
accounts.Add(accountNumber);
Console.WriteLine("Account with number " + accountNumber+ "has been added!");
}
Inside my Main I have a menu where user can choose 1.Add account where i call my method.
public static bool MainMenu()
{
Bank myBank = new Bank(accounts, 0); <----- Error here,
switch ()
{
case "1":
// Function
Console.WriteLine("Write the account number desired:");
int userInput= Convert.ToInt32(Console.ReadLine());
myBank.AddNewAccount(userInput);
return true;
case "2":
// Function
Line 3 in my MainMenu it says "The name 'accounts' does not exist in the current context".
The problem is that "accounts" doesn't exist, you have not created any variable called accounts yet. To solve the issue do the following:
var accounts = new List<int>();
Bank myBank = new Bank(accounts, 0);
OR
Bank myBank = new Bank(new List<int>(), 0);
You can just use default constructor in your class, like this :
class Bank
{
public Bank()
{
this.accounts = new List<int>();
this.number_of_accounts = 0;
}
... rest of code (from your original question)
}
You must pay attention to some things:
Usually private is used to fields, not for properties. You have full control of your private fields, so usually you don't define as a private properties.
private readonly List<int> accounts;
private int number_of_accounts;
Also, number_of_accounts is redundant. It's accounts.Count. So it's better use accounts.Count and avoid problems if you forget update number_of_accounts when you modify accounts.
number_of_accounts must be public (and a property instead of a field because is public) and only with get (without set because you can't change the size directly, you do that inserting or removing values).
public int number_of_accounts => accounts.Count;
You don't need a constructor with a list of accounts. Simply create the list. Later, with methods like AddNewAccount, you add elements.
public Bank()
{
this.accounts= new List<int>();
}
You can have a constructor with an initial list of values if you want. But avoid use that list because outside, your code can modify the list and it's better that your class have all control about their fields.
public Bank(List<int> accounts)
{
this.accounts= new List<int>();
this.accounts.AddRange(accounts);
}

How to copy a record to another record using the with keyword in C# net5.0

I am learning C# and trying to write code using records but also implementing dependency inversion.
I have a factory class that I use to create instances of my records called human.
I also use an interface of human which I assume makes my code more loosely coupled and thus implementing dependency inversion (I hope).
I create an instance of human called Paul. When I try to copy Paul using the
with
keyword so I can change the records name to James, I get an error.
paul is not null here. The receiver type 'IHuman' is not a valid record type.
What am I doing wrong? Here is my code..
Program.cs
class Program
{
static void Main(string[] args)
{
IHuman paul = Factory.CreateHuman(37, "Male", 5.11, "paul lag");
IHuman james = paul with { Name="james bond"};
Console.WriteLine(paul);
Console.WriteLine(james);
paul.Living();
Console.ReadLine();
}
}
Human.cs
public record Human(int Age, string Sex, double Height, String Name) : IHuman
{
public void Living()
{
Console.WriteLine("This Human is Living");
}
}
Factory.cs
public static class Factory
{
public static IHuman CreateHuman(int age,string sex, double height,string name)
{
return new Human(age,sex,height,name);
}
}
IHuman.cs
public interface IHuman
{
int Age { get; init; }
double Height { get; init; }
string Name { get; init; }
string Sex { get; init; }
void Deconstruct(out int Age, out string Sex, out double Height, out string Name);
bool Equals(Human? other);
bool Equals(object? obj);
int GetHashCode();
void Living();
string ToString();
}
The problem is that IHuman is an interface so the compiler can't be sure it's going to be a record. Consider the case where another class that implements the same interface, that would throw an exception if you tried to use with.
You could cast to Human either when you do the with:
IHuman james = (Human)paul with { Name = "james bond" }
or when you get the object in the first place:
Human paul = Factory.CreateHuman(37, "Male", 5.11, "paul lag") as Human;
but they are both a code smell. I really don't see the need for this interface in the first place though. You've essentially copied all of the methods from the record. So my advice would be to get rid of it and work directly with the Human object.

Constructor car calculator program

I am trying to write a program with the instructions below. The program does work currently, but it does not fully meet the specs.
I think I'm very close, but I'm having trouble understanding the constructor setup and how to do the current year.
Coding Instructions
Create a class called Car.
This class should have 3 member variables:
a string called Make
a string called Model
an integer called Year
The class should have a function that returns the age of the car by subtracting the member variable "year" from the current year (2021).
The class should have a constructor that takes 3 parameters: make, model, year.
This is my code:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Welcome to Historic Car Calculator");
Console.WriteLine("Please enter the make of your car");
var _Make = Console.ReadLine();
Console.WriteLine("Please enter the model of your car.");
var _Model = Console.ReadLine();
Console.WriteLine("Please enter the year your car was made.");
int _Year = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your " + _Make + " " + _Model+ " is " + (2021 - _Year) + " years old");
}
public class Car
{
public string Make;
public string Model;
public int Year;
public int currentYear;
//Overloaded Constructor
public Car(string _Make, string _Model, int _Year)
{
Make = _Make;
Model = _Model;
Year = _Year;
}
public void display()
{
var Car = new Car(Make, Model, Year);
}
public void CarAge(int Year)
{
this.currentYear = 2021 - this.Year;
}
}
}
1.You need to declare those 3 member variables as private, if they are public it can be accessed (for both getting and setting values), and that's what we don't want. In your case constructor should be the only means of setting their values:
private string Make;
private string Model;
private int Year;
2.There is no need for an extra variable, you can just return the car age directly:
public int GetCarAge()
{
return 2021 - Year;
}
3.The Display method creates another instance of the car class, which is wrong. you may want to return some string value about current car, or something like that:
public string display()
{
return "Make: " + Make + ", Model: " + Model + ", Year:" + Year.ToString();
//return $"Make: {Make}, Model:{Model}, Year:{Year}"; //can be written like this too
}
You have a class, but you are not using it. Lets make it a bit more meaningfull, construct an instance of a car and use it for writing:
public class Car
{
public readonly string Make;
public readonly string Model;
public readonly int Year;
public Car(string make, string model, int year)
{
Make = make;
Model = model;
Year = year;
}
public int CarAge()
{
return DateTime.Now.Year - Year;
}
}
static void Main(string[] args)
{
Console.WriteLine("Welcome to Historic Car Calculator");
Console.WriteLine("Please enter the make of your car");
var make = Console.ReadLine();
Console.WriteLine("Please enter the model of your car.");
var model = Console.ReadLine();
Console.WriteLine("Please enter the year your car was made.");
int year = Convert.ToInt32(Console.ReadLine());
var car = new Car(make, model, year);
Console.WriteLine("Your " + car.Make + " " + car.Model + " is " + car.CarAge() + " years old");
Console.ReadKey();
}
I see you have a variable for currentYear which is not needed. The current year isn't information that relates to the car. Also your function needs to return a value. So look at the sample code below for inspiration.
public class Car
{
// private fields
string make;
string model;
int year;
//Overloaded Constructor
public Car(string make, string model, int year)
{
this.make = make;
this.model = model;
this.year = year;
}
// public properties
public string Make { get { return make; } }
public string Model { get { return model; } }
public int Year { get { return year; } }
// function to calculate age
public int CarAge(int currentYear)
{
return currentYear - year;
}
// convert class to string for dsplay
public string ToString()
{
return $"{year} {make} {model} is {CarAge(DateTime.Now.Year))} years old.";
}
}
Additional functionality I included below by overriding ToString() which allows you to write things like Console.WriteLine(car) and it will display the specific information about the car. This method tells the computer how to convert the data in a class to a string representation for display or processing.
You need to be aware that Program and Car are two separate classes, even though you have declared Car inside the Program class.
In your static Main method, you need to instantiate (create) an instance (object) of the Car class with the parameters captured from your calls to Console.ReadLine():
public static void Main()
{
Console.WriteLine("Welcome to Historic Car Calculator");
Console.WriteLine("Please enter the make of your car");
var make = Console.ReadLine();
Console.WriteLine("Please enter the model of your car.");
var model = Console.ReadLine();
Console.WriteLine("Please enter the year your car was made.");
int year = Convert.ToInt32(Console.ReadLine());
// Create a Car Object using the above parameters:
// This is the proof that:
// The class should have a constructor that takes 3 parameters: make, model, year.
Car car = new Car(make, model, year);
// Deliberately demonstrate you have an Age function by
// calling the Age function on the car:
Console.WriteLine("Your car's age is {0} years old", car.Age());
// Override standard Object.ToString() to create a string representation
// Instead of creating a new method called display().
Console.WriteLine("Your Car: {0}", car);
}
You should should get into the habit of using Properties to represent the meta-data of the car, the following code will use the auto-properties syntax to declare these properties as readonly:
public string Make { get; }
public string Model { get; }
public int Year { get; }
remove currentYear... that is not needed at all.
There is a comment about an overloaded constructor... But you have not overloaded anything. At the very least you should remove that comment.
If your class needs to support serilization, then it will be important to create an additional default constructor that takes no parameters, but then the backing properties will also need to be settable from external contexts. Serilization is an important consideration for all classes in modern programming as we commonly use serilization techniques to transfer data between APIs and files, in a real world application you would want your Car instance to be saved to a database or disk, a user does not re-enter their car details, for every car, every time they use your app. This is where serialization becomes very useful, I'll include an example of this at the end of this post.
4 things about your CarAge function:
You are not using the value of Year argument at all, so remove it.
The name is redundant, we already know it is a Car Car.CarAge() is just a silly, make your code easier to read by renaming to something that includes a verb to describe what it does like CalculateAge() or perhaps just simply Age().
You do not need to create a new instance of a Car, this method is already part of a car definition, so it has access to the member variables.
This is contraversial... at least from a homework point of view, the value of 2021 should NOT be hardcoded, even though the requirement suggests this. In real world software design hardcoding time, system or environment based variables is a serious red flag
In .NET DateTime.Now will give you the current time and date, from there you can access the current year.
public int Age()
{
return DateTime.Now.Year - this.Year;
}
Finally, replace your display method with an override of the standard Object.ToString(). That is the whole purpose of the ToString() to create the standard display representation of your class.
public override string ToString()
{
return String.Format("Make: {0}, Model: {1}, Year: {2}, Age: {3}", this.Make, this.Model, this.Year, this.Age();
// You could also use string interpolation:
// return $"Make: {this.Make}, Model: {this.Model}, Year: {this.Year}, Age: {this.Age()}";
}
Overall this makes your Car class look something like this:
public class Car
{
public string Make { get; }
public string Model { get; }
public int Year { get; }
public Car(string make, string model, int year)
{
Make = make;
Model = model;
Year = year;
}
/// <summary>Override ToString to return the standard display format for a car</summary>
public override string ToString()
{
return String.Format("Make: {0}, Model: {1}, Year: {2}, Age: {3}", this.Make, this.Model, this.Year, this.Age();
// You could also use string interpolation:
// return $"Make: {this.Make}, Model: {this.Model}, Year: {this.Year}, Age: {this.Age()}";
}
/// <summary>Caculate and return the Current Age of this Car based on the current System Year and stamp Year of this car.</summary>
public int Age()
{
return DateTime.Now.Year - this.Year;
}
}
Serialization Support
As explained above, if is a good habit to get into supporting serialization, this will enable the instances of your class to be saved to text based files or to be transferred via text based protocols like HTTP. In an increasingly cloud oriented industry, you will come across this requirement very soon.
To support Serialization in a generic sense a class needs to have the following:
A parameter-less constructor, this is known as the default constructor.
The meta-data that you want to be saved and restored MUST be declared as public Properties.
This is because the default string based serialization processors will create an instance of the target class using the default constructor and will then set each of the properties one by one.
We can add the default serialization support to your Car class by making the auto-properties settable by external contexts and by adding the default constructor:
public class Car
{
public string Make { get;set; }
public string Model { get;set; }
public int Year { get;set; }
/// <summary>Create a default Car representation, meta-data will need to be set explicitly </summary>
public Car()
{
}
/// <summary>Overload to Create a Car Instance with the specified meta-data</summary>
public Car(string make, string model, int year)
{
Make = make;
Model = model;
Year = year;
}
/// <summary>Override ToString to return the standard display format for a car</summary>
public override string ToString()
{
return String.Format("Make: {0}, Model: {1}, Year: {2}, Age: {3}", this.Make, this.Model, this.Year, this.Age();
// You could also use string interpolation:
// return $"Make: {this.Make}, Model: {this.Model}, Year: {this.Year}, Age: {this.Age()}";
}
/// <summary>Caculate and return the Current Age of this Car based on the current System Year and stamp Year of this car.</summary>
public int Age()
{
return DateTime.Now.Year - this.Year;
}
}
There are other benefits to this Serialization ready implementation, we can now avoid overloaded constructors altogether with the following class instantiation syntax:
var car = new Car { Make = make, Model = model, Year = year };

How to access value out of dictionary whose key is complex type?

In writing an insurance premium calculator the basic scheme is as follows: Points are assigned to a predetermined number of attributes, such as car-value, num-incidents-in-past, years-experience-driving etc. Hene, if car worth is $3800, that lies within the 3001 to 4000 range which warrants 30 points in the premium calculation. If num-incidents-in-past is 3 or below, that warrants ZERO points. If 4-5 num-inc then points warranted is 5. If years-exp is between 1-5, that warrants 12 points. The idea is an arbitrary value is being assigned to a range of values for any given number of attributes. The premium calculations is simply tallying up the points warranted for each attribute category and multiplying by some factor i.e 2.5. I am trying to use B. LISKOV'S power of abstractions AND the SRP to neatly assign responsiblities to design a calculator that is extensible and well designed.
Based on the answer provided by drharris here Is there a C# type for representing an integer Range?
How do I access the value out of the following Dictionary whose key is a generic type Range as defined by drharris?
//************************ABSTRACTIONS************************
public abstract class AbsPerson
{
public virtual AbsPolicy APolicy { get; set; }
public virtual string ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public virtual string Address { get; set; }
}
public abstract class AbsPolicy
{
public virtual string PersonID { get; set; } //FK
public virtual int PropValue { get; set; }
public virtual int InsGroup { get; set; }
}
public abstract class AbsValueCategoryCalculator: IEvaluatePolicy
{
//DATA
public abstract void InitRange();
//REFERENCE drharris poster GENERIC TYPE SIGNATURE - public class Range<T> where T : IComparable<T>
public abstract Dictionary<Range<int>, int> ValueRange {get; set;}
public abstract int Tally { get; set; }
//BEHAVIOUR
public virtual void EvaluatePolicyDetails(AbsPerson person)
{
}
}
public interface IEvaluatePolicy
{
void EvaluatePolicyDetails(AbsPerson person);
}
//*************************CONCRETIONS**************************
public class CarValueCategoryCalculator : AbsValueCategoryCalculator
{
public CarValueCategoryCalculator()
{//ctor
InitRange();
}
public override void InitRange()
{
this.ValueRange = new Dictionary<Range<int>, int>();
this.ValueRange.Add(new Range<int>() { Minimum = 1000, Maximum = 2000 }, 10);
this.ValueRange.Add(new Range<int>() { Minimum = 2001, Maximum = 3000 }, 20);
this.ValueRange.Add(new Range<int>() { Minimum = 3001, Maximum = 4000 }, 30);
this.ValueRange.Add(new Range<int>() { Minimum = 4001, Maximum = 5000 }, 40);
this.ValueRange.Add(new Range<int>() { Minimum = 5001, Maximum = 6000 }, 50);
this.ValueRange.Add(new Range<int>() { Minimum = 6001, Maximum = 7000 }, 60);
}
public override Dictionary<Range<int>, int> ValueRange
{
get; set;
}
public override void EvaluatePolicyDetails(AbsPerson person)
{
//I am trying to tally the value given wether the cars worth lies within the range
if (this.ValueRange.ContainsKey(new Range<int>() { Maximum = person.APolicy.PropValue, Minimum = person.APolicy.PropValue }))
{
this.Tally =
}
Console.WriteLine("good");
}
public override int Tally
{
get;set;
}
}//end class
(As noted in comments, Sam's answer points out that a dictionary isn't really what's wanted here - that only finds equal keys, whereas the OP is trying to find a range key that contains a single value. Hash tables just aren't geared up for that.)
You need to either override GetHashCode and Equals in Range<T> (which would be sensible - ideally implementing IEquatable<Range<T>> at the same time) or create a separate type which implements IEqualityComparer<Range<T>> and then pass that to the dictionary constructor.
I would probably do it on the range type, like this:
public sealed class Range<T> : IEquatable<Range<T>>
where T : IComparable<T>, IEquatable<T>
{
...
public override int GetHashCode()
{
int hash = 23;
hash = hash * 31 + EqualityComparer.Default<T>.GetHashCode(Minimum);
hash = hash * 31 + EqualityComparer.Default<T>.GetHashCode(Maximum);
return hash;
}
public override bool Equals(object other)
{
return Equals(other as Range<T>);
}
public bool Equals(Range<T> other)
{
if (ReferenceEquals(other, this))
{
return true;
}
if (ReferenceEquals(other, null))
{
return false;
}
return EqualityComparer<T>.Default.Equals(Minimum, other.Minimum) &&
EqualityComparer<T>.Default.Equals(Maximum, other.Maximum);
}
}
Note that currently the Range<T> type is mutable, however - that's generally a bad idea for dictionary keys. It would be a good idea to make it at least "shallow-immutable" - there's not a lot you can do if the
You'll either need to override Equals and GetHashCode on Range such that the items are compared based on the values you're interested in (min and max) rather than the default behavior (which is based on the object's reference).
If you cannot mutate the type (or don't want to) then you can create a type that implements IEqualityComparer<Range<T>>, implements the appropriate equals and hash generation methods, and then create an instance of that comparer that you pass to the dictionary.
I'm trying to read between the lines here, and I think that you are asking the wrong question.
This bit of code catches my eye (you may want to make it clearer so that others understand your need better):
public override void EvaluatePolicyDetails(AbsPerson person)
{
//I am trying to tally the value given wether the cars worth lies within the range
if (this.ValueRange.ContainsKey(new Range<int>() { Maximum = person.APolicy.PropValue, Minimum = person.APolicy.PropValue }))
{
this.Tally =
}
Console.WriteLine("good");
}
I think that what you are actually trying to do here is fetch the associated int value when person.APolicy.PropValue is within a Range.
What you are currently doing is wrong, and will not work, even if you add the proper Equals and GetHashCode overrides. Dictionaries only do exact matches. You are trying to do range matching.
Instead, I suggest you drop the dictionary in favor of a List of a new type composed of a Range and whatever that int value is. Then I would sort the list based on the Range's Minimum value. Then, you could optionally do a binary search in the list to quickly find candidate Range objects, and then use the Range.ContainsValue function to verify if person.APolicy.PropValue is within the range. Or, in this case, given that you only have a handful of Ranges, you can just iterate over the whole list and break out of the loop as soon as you find a Range that contains your value.
This is definitely a bit more work for you, but I think that this will get you what you are really looking for.

How can I see all instances of a class?

I have a short presentation at school for relations between classes (UML), and I want to show with code how composition and aggregation work in practical use and the difference between them. In order to do that however I want to be able to be able to see all active objects atm, to proove that the object I deleted and the object that was part of it are truly gone now.
This is a quick example of what I am trying to do:
List<Company>companies = new List<Company>(){
new Company(){
Name = "Greiner",
new Boss(){
Name = "Hugo",
},
},
};
Company comp = companies.FirstOrDefault();
companies.Remove(comp);
Now I want to somehow show that the Boss is gone along with the company, not just the (indirect) reference to him. So I thought of looking at all active objects.
Is there any way to do this? I am aware that the garbage collector is supposed to do this, but I dont want to tell my fellow students to just believe my words.
Also I do tend to think overly complicated, so my approach might be completely backwards, so any suggestions how to proove the differences between aggregation and composition are welcome.
Regards
Andreas Postolache
You can keep a static counter within your classes to keep count of the no. of instances created. Increment this counter in the constructor and decrease it in the destructor. The class structure sample is shown below.
public class Company
{
public static int counter = 0;
public Company()
{
counter++;
}
public string Name {get;set;}
public Boss Boss { get; set; }
~Company()
{
counter--;
}
}
public class Boss
{
public static int counter = 0;
public Boss()
{
counter++;
}
public string Name {get;set;}
~Boss()
{
counter--;
}
}
Now you can see the no. of instances by printing this counter wherever required.
You can now instantiate your class Company and check the count of objects.
Company company = new Company(){ Name = "Greiner", Boss = new Boss(){ Name = "Hugo" }} ;
Console.WriteLine("Company: " + Company.counter.ToString());
Console.WriteLine("Boss: " + Boss.counter.ToString());
company = null;
The output should result in Company: 1 and Boss: 1
Now on a Button Click write the following code
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Company: " + Company.counter.ToString());
Console.WriteLine("Boss: " + Boss.counter.ToString());
Note that you will have to call the garbage collection methods to force immediate collection or else you cannot guarantee when the object will be removed by the GC.
The output will now show 0 for both Company and Boss.
Note: Use GC.Collect only in your classroom for demonstration purposes.
Garbage collection complicates things for you here - perhaps it would be more instructional to show this in native C++ instead. However, you can explicitly call GC.Collect() to force the garbage collection. To be able to track the deletion of the object, you can use the destructor:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ExampleDeletion
{
class Program
{
public class Company
{
public string Name { get; set; }
public Boss CEO { get; set; }
~Company()
{
Console.WriteLine("Company destroyed: " + Name);
}
}
public class Boss
{
public string Name { get; set; }
~Boss()
{
Console.WriteLine("Boss destroyed: " + Name);
}
}
static void Main(string[] args)
{
List<Company> companies = new List<Company>();
Add(ref companies);
Remove(ref companies);
GC.Collect();
Console.ReadLine();
}
static private void Add(ref List<Company> companies)
{
companies.Add(
new Company()
{
Name = "Greiner",
CEO = new Boss()
{
Name = "Hugo"
}
});
}
static private void Remove(ref List<Company> companies)
{
Company comp = companies.FirstOrDefault();
companies.Remove(comp);
}
}
}
One interesting thing I have noticed while trying this out is that if you remove the item from the list in the same scope where it was created, it does not get collected by GC. It looks like there is an implicit reference from the current scope which keeps the object alive. That was the reason why I pushed the creation of the item to a separate function.

Categories