I have tried to add 2 types of objects in an Array List and then have tried to display them but somehow it is not working. Do I need to use 2 Array List objects or how is it going to work?
Error Message:
Unable to cast object of type 'ArrayList_Practice.Student' to type
'ArrayList_Practice.Employees'.
class Program
{
static void Main(string[] args)
{
Student st=null;
Employees emp = null;
ArrayList al = new ArrayList();
Console.WriteLine("Enter Records");
for (int i = 0; i < 2; i++)
{
st = new Student();
Console.WriteLine("Enter roll");
st.roll = int.Parse(Console.ReadLine());
Console.WriteLine("Enter name");
st.name = Console.ReadLine();
Console.WriteLine("Enter course");
st.course = Console.ReadLine();
al.Add(st);
emp = new Employees();
Console.WriteLine("Enter empID");
emp.empID = int.Parse(Console.ReadLine());
Console.WriteLine("Enter name");
emp.name = Console.ReadLine();
al.Add(emp);
}
Console.WriteLine("/////////////Show Records//////////");
for (int i = 0; i < 2; i++)
{
Console.WriteLine("Roll "+((Student)al[i]).roll.ToString());
Console.WriteLine("Name "+((Student)al[i]).name);
Console.WriteLine("Course "+((Student)al[i]).course);
Console.WriteLine("EmpID "+((Employees)al[i]).empID.ToString());
Console.WriteLine("EmpName "+((Employees)al[i]).name);
}
Console.ReadKey();
}
}
class Student
{
public int roll{ get; set;};
public string name{ get; set;};
public string course{ get; set;};
}
class Employees
{
public int empID{ get; set;};
public string name{ get; set;};
}
}
Your first element is a Student, and you are trying to cast it to Employee on first iteration in the loop.That's why you are getting an InvalidCastException in run-time.Don't use ArrayLists, use strongly-typed generic collections instead.For ex: List<T>.
If you want to display common properties and you want to store Students and Employees into the same list, you can create a common interface for them and implement it.Then you can have a List<CommonInterface> and store your instances.But if you have different properties (it seems you have) you can't access them using common interface or base class,instead you can simply create an extension method and use Reflection to display all property values like this:
public static class Extensions
{
public static string DisplayPerson<T>(this T source)
{
if(source == null) throw new ArgumentNullException("source");
var flags = BindingFlags.Instance | BindingFlags.Public;
var properties = source.GetType().GetProperties(flags);
if (properties.Any())
{
StringBuilder sb = new StringBuilder();
foreach (var prop in properties)
{
sb.AppendFormat("{0} : {1}", prop.Name, prop.GetValue(source));
sb.AppendLine();
}
return sb.ToString();
}
return string.Empty;
}
}
Then just call it from the loop:
for (int i = 0; i < al.Count; i++)
{
Console.WriteLine(al[i].DisplayPerson());
}
Edit: Another way using common interface
public interface IPerson
{
string Name { get; set; }
int Id { get; set; }
}
class Student : IPerson
{
/* implement the properties */
}
class Employees : IPerson
{
/* implement the properties */
}
static void Main(string[] args)
{
List<IPerson> personList = new List<IPerson>();
personList.Add(new Student {/* set properties */});
personList.Add(new Employee {/* set properties */});
// use a loop and display your properties without casting
}
in your array list, your 0th element is a student type and 1st element is an employee type.
in your loop, then you're trying to cast your 0th element to an employee to display empID.
hence you need to be aware of this..
you need to do proper cast check for the loop to work.
check if the element is student or employee and display accordingly.
for (int i = 0; i < al.Count; i++)
{
var student = al[i] as Student;
if (student != null)
{
Console.WriteLine("Roll "+ student.roll.ToString());
Console.WriteLine("Name "+ student.name);
Console.WriteLine("Course "+ student.course);
}
else
{
var employee = al[i] as Employee;
if (employee != null)
{
Console.WriteLine("EmpID "+ employee.empID.ToString());
Console.WriteLine("EmpName "+ employee.name);
}
}
}
though this works for your problem, in general you should be using strongly types collections.
e.g. List<Student> and List<Employee>
You need two lists, because you are trying to store two different types of objects in the array. While it's possible to manage this, you'd be better off keeping it simple: have an array for students and an array for employees.
I'm not sure why you enter the student and employee records at the same time, in pairs. Are the employees connected to the students in some way? Are the students employees? If so, you'd be better off creating a single object that represents student-employee, or whatever the relationship is, and filling a single list with items of that type.
Also, it's 2014 and you shouldn't be using ArrayList. At the very least, use List<>.
Related
I'm trying to loop through an array of objects and print their properties from a different class.
My main class is
class Program
{
static void Main()
{
//This to be change to relative path
string Path = #"C:\Users\";
string[] lines = { }; ;
//Reading file
if (File.Exists(Path))
{
lines = File.ReadAllLines(Path);
StudentReport.ReadStudents(lines);
}
else
{
Console.WriteLine("The file does't exist");
}
//Printing Students
PrintStudent.Print(lines.Length);
}
}
I'm using this code to declare the array
public class StudentReport
{
public static void ReadStudents(string[] Lines)
{
//declare an array with the number of students
Student[] studentArray = new Student[Lines.Length];
int StudentCounter = 0;
foreach (string Line in Lines)
{
String[] Student = Line.Split(',');
//Calculating values
string ID = Student[0].PadLeft(10, '0');
string name = Student[1];
//Initialize the object
studentArray[StudentCounter] = new Student
{
FullName = name,
ID = ID,
};
StudentCounter++;
}
}
}
And I'm using this class to construct my student object
class Student
{
public string FullName { get; set; }
public string ID { get; set; }
}
To output the student object properties, I made another class. The problem is that I couldn't access the value of the objects array from my new class.
The class I made for outputting purposes is the following, but I cannot get the values. The error is 'Student does not contain a definition for student array
public class PrintStudent
{
public static void Print(int StudentCounter)
{
for(int i = 0; i > StudentCounter; i++)
{
Console.WriteLine(Student.studentArray[i].FullName);
}
}
}
Your error is Student does not contain a definition for studentArray. This is because your Student class does not have studentArray, only the properties FullName and ID. So accessing Student.studentArray[i] doesn't make sense.
Probably what you want is for ReadStudents to return the studentArray so it doesn't go out of scope by changing the method signature to return the Student[], and calling return studentArray at the end.
Then, you can pass your studentArray to your PrintStudent.Print method in the parameters.
By the way, the for(int i = 0; i > StudentCounter; i++) has a wrong < and will never run (lines.Length which is the StudentCounter will always be >= 0)
You can use studentArray.Length, or a foreach loop to iterate over this array, rather than pass the StudentCounter.
There are semi answer to this question which I have read through thoroughly, as well as all things MSDN about generic classes but I am still having trouble when a generic class inherits from another class: where T: ClassName
For example, here is my generic list class
public class MyGenericList2<T> where T : Person
{
private T[] list;
public MyGenericList2(int size)
{
list = new T[size];
}
public T getItem(int index)
{
T temp = default(T);
temp = list[index];
return temp;
}
public void setItem(int index, T value)
{
list[index] = value;
}
public void DisplayList()
{
for (int i = 0; i < list.Length; i++)
{
Console.Out.WriteLine(list[i]);
}
}
}
It inherits from the person class:
NOTE: It is shortened for clarity sake
public abstract class Person
{
protected string firstName;
// Getters
public string getFirstName()
{
return this.firstName;
}
public void setFirstName(string fname)
{
this.firstName = fname;
}
}
When I try to call it I get an error about trying to convert a string to a {namespace}.Person which I sort of get, in that I am trying to put a string into a 'Person' box, but how does one call the class using this mechanism?
Here is the main method
public static void Main(string[] args)
{
MyGenericList2<Person> studentGeneric = new MyGenericList2<Person>(3);
Student st1 = new Student();
st1.setFirstName("Thor");
studentGeneric.setItem(0, st1); //This does not work
studentGeneric.setItem(1, Person.setFirstName("Odin"); // Does not work
studentGeneric.setItem(2, st1.setFirstName("Slepnir"); // Does not work
studentGeneric.DisplayList();
Console.ReadLine();
}
If I cut out the Where T : Person and use GenericList2<string> it works fine, which makes sense since it is string to string.
Any help would be appreciated
quick clarification Student inherits from Person:
public class Student : Person
{
// Student 1
private string studentID01 = "001";
public string getStudentID01()
{
return this.studentID01;
}
}
First of all I would recommend using public properties for your classes, for example:
public abstract class Person
{
public string FirstName { get; set; }
}
public class Student : Person
{
public string StudentId { get; set; }
}
This means your list code would work like this:
Student st1 = new Student();
st1.FirstName = "Thor";
studentGeneric.setItem(0, st1);
And you can even use this syntax:
studentGeneric.setItem(1, new Student
{
FirstName = "Odin"
});
Additionally, the .Net Framework already provides a really nice set of generic collection classes you can use so you don't really need your MyGenericList2<T> class. For example, the most commonly used class is System.Collections.Generic.List:
var people = new System.Collections.Generic.List<Person>();
people.Add(new Student
{
FirstName = "Odin"
});
Or even using the collection initialiser syntax:
var people = new System.Collections.Generic.List<Person>
{
new Student
{
FirstName = "Odin"
}
});
Finally, the problem you are having with outputting your values to the console is because C# doesn't know what to do with your class so by default outputs the value of student.ToString(). And becaue you haven't told your class what to do with it, it just outputs the name of the type. You can either override ToString or, much simpler just call the getFirstName() method:
Console.WriteLine(list[i].getFirstName());
You are using setItem incorrectly. This method can be used to set the value of elements in the list array in an instance of MyGenericList2 class.
To use the setFirstName method on an instance of the Student class, first use getItem to return the object instance. For example:
public void Main(string[] args)
{
MyGenericList2<Person> studentGeneric = new MyGenericList2<Person>(3);
Student st1 = new Student();
st1.setFirstName("Thor");
studentGeneric.setItem(0, st1);
Student st2 = new Student();
studentGeneric.setItem(1, st2);
studentGeneric.getItem(1).setFirstName("Odin");
Student st3 = new Student();
studentGeneric.setItem(2, st3);
studentGeneric.getItem(2).setFirstName("Slepnir");
studentGeneric.DisplayList();
Console.ReadLine();
}
To display the list contents correctly, replace your DisplayList() method with:
public void DisplayList()
{
for (int i = 0; i < list.Length; i++)
{
if(list[i] != null){
Console.Out.WriteLine("{0}: {1}", i, list[i].getFirstName());
}
else
{
Console.Out.WriteLine("{0}: [NULL]", i);
}
}
}
Having a model something like this (I cannot change this):
public class SomeObject
{
public int Amount { get; set; }
public int TotalAmount { get; set; }
}
I need to iterate an array of SomeObject to populate some values and accumulate (perform not simple calculations) another fields.
static void Main(string[] args)
{
List<SomeObject> myCollection = new List<SomeObject>()
{
new SomeObject() { Amount = 3 },
new SomeObject() { Amount = 6 },
new SomeObject() { Amount = 9 }
};
int totalAccumulated = 0;
for (int i = 0; i < myCollection.Count; i++)
{
PopulateAndCalculate(myCollection[i], ref totalAccumulated);
}
//I don't want to create here a second for to iterate again all myCollection to set his TotalAmount property.
//There is another way?
Console.WriteLine($"The total accumulated is: {totalAccumulated}");
}
private static void PopulateAndCalculate(SomeObject prmObject, ref int accumulatedTotal)
{
//Populate a lot of another fields
accumulatedTotal += prmObject.Amount;
prmObject.TotalAmount = accumulatedTotal; //This don't work, but I need something alike
}
I don't want a second for statement to update TotalAmount property of each item in myCollection.
The main requirement is iterate the whole array, few times, don't care about string interpolation this is a short demo, this code must run in .net 2.0.
Theres is a clean/better way?
The solution is actually simple, though it's not exactly a good coding practice.
What you really need is for TotalAmount to be a static property. Without that, there's this:
static void Main(string[] args)
{
List<SomeObject> myCollection = new List<SomeObject>()
{
new SomeObject() { Amount = 3 },
new SomeObject() { Amount = 6 },
new SomeObject() { Amount = 9 }
};
int totalAccumulated = 0;
for (int i = 0; i < myCollection.Count; i++)
{
PopulateAndCalculate(myCollection[i], ref totalAccumulated);
}
/*****This is the new part*******/
myCollection[0].TotalAmount = totalAccumulated;
myCollection[1].TotalAmount = totalAccumulated;
myCollection[2].TotalAmount = totalAccumulated;
Console.WriteLine($"The total accumulated is: {totalAccumulated}");
}
private static void PopulateAndCalculate(SomeObject prmObject, ref int accumulatedTotal)
{
//Populate a lot of another fields
accumulatedTotal += prmObject.Amount;
//no need to mess with the total here as far as the properties are concerned.
}
You can st fields inside linq expression.
Could you consider this please
myCollection.ForEach(c => c.TotalAmount = myCollection.Sum(a => a.Amount));
Console.WriteLine($"Total accumulated :{myCollection.First().TotalAmount}");
I found a solution using the Observer Pattern.
Firstly I created a global delegate to be used by an event:
public delegate void UpdateTotalAmountDelegate(int totalAmount);
Then a new class called: 'CalculatorSetter'
public class CalculatorSetter
{
public event UpdateTotalAmountDelegate UpdateTotalAmounthHandler;
public void UpdateTotalAmount(int prmTotalAmount)
{
UpdateTotalAmounthHandler(prmTotalAmount);
}
}
I refactor the data object 'SomeObject' adding a field of type CalculatorSetter.
public class SomeObject
{
private CalculatorSetter finalCalculator;
public void SetCalculator(CalculatorSetter prmCalculator)
{
this.finalCalculator = prmCalculator;
finalCalculator.UpdateTotalAmounthHandler += FinalCalculator_UpdateTotalAmounthHandler;
}
private void FinalCalculator_UpdateTotalAmounthHandler(int totalAmount)
{
this.TotalAmount = totalAmount;
}
//Some Other Fields
public int Amount { get; set; }
public int TotalAmount { get; set; }
}
And my original code and unique for:
static void Main(string[] args)
{
List<SomeObject> myCollection = new List<SomeObject>()
{
new SomeObject() { Amount = 3 },
new SomeObject() { Amount = 6 },
new SomeObject() { Amount = 9 }
};
CalculatorSetter commonCalculator = new CalculatorSetter();
int totalToAccumulate = 0;
for (int i = 0; i < myCollection.Count; i++)
{
PopulateAndCalculate(myCollection[i], commonCalculator, ref totalToAccumulate);
}
commonCalculator.UpdateTotalAmount(totalToAccumulate);
Console.WriteLine($"The total accumulated is: {totalToAccumulate}");
Console.WriteLine($"The first total accumulated is: {myCollection[0].TotalAmount}");
}
Many thanks.
Use a wrapper and keep it simple (if you want you can change a little for use static methods you can, or static class but I dont see the point)
the result is:
The Amount is 3, The total ammount is 18
The Amount is 6, The total ammount is 18
The Amount is 9, The total ammount is 18
namespace Prueba1
{
class Program
{
public class WrapperInt {
public int Value { get; set; }
}
public class SomeObject
{
public int Amount { get; set; }
public WrapperInt TotalAmount { get; set; }
}
public Program() {
WrapperInt TotalAmountAllArrays = new WrapperInt();
List<SomeObject> myCollection = new List<SomeObject>()
{
new SomeObject() { Amount = 3, TotalAmount =TotalAmountAllArrays },
new SomeObject() { Amount = 6 , TotalAmount =TotalAmountAllArrays },
new SomeObject() { Amount = 9 , TotalAmount =TotalAmountAllArrays }
};
for (int i = 0; i < myCollection.Count; i++)
{
myCollection[i].TotalAmount.Value += myCollection[i].Amount;
}
foreach (var c in myCollection)
{
Console.WriteLine($"The Amount is:" + c.Amount + " The total ammount is:" + c.TotalAmount.Value);
}
}
static void Main(string[] args)
{
new Program();
}
}
}
Hopefully this will work for you… One possible solution is to create a wrapper class called MyTotalList which contains a List named amounts and an int named total. MyTotalList class does not expose its list amounts as an editable list. If the class exposes this list as editable, then other methods could ultimately change an items value in that list and the MyTotalList class would not be aware of this and unfortunately contain an incorrect total. To avoid this situation and for the class to work as expected, methods must use the MyTotalList’s Add and Remove methods. To ensure this happens, the private List amounts in the MyTotalList class returns a read only list which ensures that changes to the list will not be made outside the MyTotalList class. Leaving the list exposed and editable will/could cause the class to contain an incorrect total.
My solution is to create a Class that wraps a List. MyTotalList class has a no argument constructor. Once a new instance of a MyTotalList object is created you can then use that instance to Add MyObject items to its list. Every time an item is added to the MyTotalList, list amounts the variable total gets updated with the added item’s amount. Example:
Create a new MyTotalList object:
MyTotalList listOfObjects = new MyTotalList();
Then add some MyObject instances to the listOfObjects
listOfObjects.Add(new MyObject(1,3));
listOfObjects.Add(new MyObject(2,6));
listOfObjects.Add(new MyObject(3,9));
After you add the items, you can then use the listOfObjects Total property to get the total sum of all MyObject items in the list with:
listOfObjects.Total
If you need to pass or use the List of MyTotalList items you can use:
listOfObjects.Items
Bear in mind as I discussed above, this List Items is a read-only list. Therefore you cannot add/remove items in this list as you would an editable list. So the code below will fail during implementation as these methods are not exposed for read only objects.
listOfObjects.Items.Remove(new MyObject(4, 10));
listOfObjects.Items.Add(new MyObject(4, 10));
The above lines will cause the compiler to complain: xxx… does not contain a definition for Add/Remove. This ensures methods will use the MyTotalList.Add and MyTotalsList.Remove methods and eliminate any possibility of the list changing outside the MyTotalList class.
MyObject Class
class MyObject : IComparable {
public int id { get; }
public int amount { get; }
public MyObject(int inID, int inAmount) {
id = inID;
amount = inAmount;
}
public override string ToString() {
return amount.ToString();
}
public override int GetHashCode() {
return id.GetHashCode();
}
public override bool Equals(object other) {
if (other != null)
return (this.id == ((MyObject)other).id);
return false;
}
public int CompareTo(object other) {
if (this.id > ((MyObject)other).id)
return 1;
if (this.id < ((MyObject)other).id)
return -1;
return 0;
}
}
MyTotalList Class
class MyTotalList {
private int total;
private List<MyObject> amounts;
public MyTotalList() {
total = 0;
amounts = new List<MyObject>();
}
public int ListCount {
get { return amounts.Count; }
}
public IReadOnlyCollection<MyObject> Items {
get { return amounts.AsReadOnly(); }
}
public int Total {
get { return total; }
}
public void Add(MyObject other) {
if (other != null) {
if (!(amounts.Contains(other))) {
total += other.amount;
amounts.Add(other);
}
else {
Console.WriteLine("Duplicate id's not allowed!");
}
}
}
public void Remove(MyObject other) {
if (amounts.Contains(other)) {
total -= amounts[amounts.IndexOf(other)].amount;
amounts.Remove(other);
}
else {
Console.WriteLine("Item to remove not found!");
}
}
}
Examples
MyTotalList listOfObjects = new MyTotalList();
listOfObjects.Add(new MyObject(1,3));
listOfObjects.Add(new MyObject(2,6));
listOfObjects.Add(new MyObject(3,9));
Console.WriteLine("----------------------------------------");
Console.WriteLine("Initial list with total");
Console.WriteLine("items in list:");
foreach (MyObject mo in listOfObjects.Items)
Console.Write(mo.ToString() + " ");
Console.WriteLine();
Console.WriteLine("Total from list of " + listOfObjects.ListCount +
" items is: " + listOfObjects.Total);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Add three more items");
listOfObjects.Add(new MyObject(4, 10));
listOfObjects.Add(new MyObject(5, 11));
listOfObjects.Add(new MyObject(6, 12));
Console.WriteLine("items in list:");
foreach (MyObject mo in listOfObjects.Items)
Console.Write(mo.ToString() + " ");
Console.WriteLine();
Console.WriteLine("Total from list of " + listOfObjects.ListCount +
" items is: " + listOfObjects.Total);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Remove id 4 (10) from the list");
listOfObjects.Remove(new MyObject(4, 10));
Console.WriteLine("items in list:");
foreach (MyObject mo in listOfObjects.Items)
Console.Write(mo.ToString() + " ");
Console.WriteLine();
Console.WriteLine("Total from list of " + listOfObjects.ListCount +
" items is: " + listOfObjects.Total);
A Side note to your original post…About the class you can not change
SomeObject {
public int Amount { get; set; }
public int TotalAmount { get; set; }
}
Regardless of how you get the total for theint varable: TotaAmount… for each instance of SomeObject class to contain the same variable with the same amount and you want to ensure this is true for all existing SomeObject instances… is well a poor design. This creates redundant data and simply waste space and it makes no sense for each variable to contain this value as it has absolutely nothing to do with that SomeObject instance. This class design is counter intuitive of a good design. As #Tim Schmelter’s comment points out "a single object should not know anything about the total amount of other objects." This “redundant data” situation is something a programmer should try to avoid, not promote.
So I have coded for a while I C# and learned the basics, one thing that always stops me is how I can create a class and then use a list for a user to input values.
I don't know if I'm totally off the chart with this code, the problem is that I don't understand why I can't use my newly created object of the class and add input to it. All help is appreciated
class Program
{
static void Main(string[] args)
{
List<Citizen> listOfCitizens = new List<Citizen>();
for (int i = 0; i < listOfCitizens.Count; i++)
{
Console.WriteLine("Enter Surname for the citizen:");
listOfCitizens.SurName.add = Console.ReadLine();
Console.WriteLine("Enter Lastname for the citizen:");
listOfCitizens.Lastname.add = Console.ReadLine();
Console.WriteLine("Enter age of the citizen:");
listOfCitizens.age.add = int.Parse(Console.ReadLine());
}
Console.WriteLine($"Name {Citizen.SurName} {Citizen.LastName} {Citizen.age}");
Console.Read();
}
}
class Citizen
{
public static string SurName{ get; set; }
public static string LastName{get;set;}
public static int age { get; set; }
}
A list of something is not a something. Just like a basket of apples is not an apple. You don't eat the basket, you eat an item from the basket.
So when you create your list:
List<Citizen> listOfCitizens = new List<Citizen>();
You would then create an item to add to the list:
Citizen someCitizen = new Citizen();
someCitizen.SurName = "Smith";
// etc.
And then add it to the list:
listOfCitizens.Add(someCitizen);
Additionally, your Citizen is a little off. Those properties shouldn't be static. Not sure why you made them that way, but you should remove the static keyword from everything in your Citizen class.
I'm working on a project where it is necessary for me to create and bind the grid to display a response from a server which is a list of classes and some fields, the lists of classes also contain some variables as well as another list of a different class which contains some fields and another list of a different class...and goes on for five levels.
I must display the top level class and all of the lists of classes as well as each of the nested lists within the list and by itself. Allow me to use pseudocode to try to better explain with a triple tier. I am dealing with a quintuple tier.
classA
{
List<classB> classBList;
List<classC> classCList;
int whatever;
string something;
}
ClassB
{
List<classC> classCList;
int somethingElse;
string otherThing;
}
classC
{
int somethingA;
string somethingB;
}
List<ClassA> list1;
I am trying to create and bind and display the grid for list1. I've mainly been a straight back end coder so the .aspx page is what is really throwing me for a loop. I've figured out how bind and display with fields and fields within classes and a single list, but these lists are really challenging for me and I haven't made any progress in a couple of days.
Any help is much appreciated!
Maybe something like where you flatten all the values down and use a dictionary to track their origin (if it's needed). You would then have a flattened list of all values, and could easily create or recreate an original list of values (those belonging to ClassA.ClassBList, for example) using Linq or the Dictionary keys themselves:
public class flattenedList
{
public string whatever;
public int whateverInt;
}
public class nested
{
private Dictionary<string, List<flattenedList>> listData = new Dictionary<string, List<flattenedList>>();
private List<ClassA> list1 = new List<ClassA>();
ClassA classA = new ClassA();
ClassB classB = new ClassB();
ClassC classC = new ClassC();
public void processCalsses()
{
string key = "";
foreach (ClassA a in list1)
{
key = "ClassA.ClassBList";
foreach (ClassB b in classA.classBList)
{
addToDictionary(key, new flattenedList() { whatever = b.otherThing, whateverInt = b.somethingElse });
}
key = "ClassA.ClassCList";
foreach (ClassC c in classA.classCList)
{
addToDictionary(key, new flattenedList() { whatever = c.somethingB, whateverInt = c.somethingA });
}
addToDictionary("ClassA", new flattenedList() { whatever = a.something, whateverInt = a.whatever });
}
key = "ClassB.ClassCList";
foreach (ClassC c in classB.classCList)
{
addToDictionary(key, new flattenedList() { whatever = c.somethingB, whateverInt = c.somethingA });
}
addToDictionary("ClassB", new flattenedList() { whatever = classB.otherThing, whateverInt = classB.somethingElse });
addToDictionary("ClassC", new flattenedList() { whatever = classC.somethingB, whateverInt = classC.somethingA });
foreach (KeyValuePair<string, List<flattenedList>> kvp in listData)
{
for (int i = 0; i < kvp.Value.Count; i++)
{
Console.WriteLine(key + "[" + i.ToString() + "] whatever = " + kvp.Value[i].whatever);
Console.WriteLine(key + "[" + i.ToString() + "] whateverInt = " + kvp.Value[i].whateverInt.ToString() + "\n");
}
}
}
private void addToDictionary(string key, flattenedList f)
{
if (!listData.ContainsKey(key))
{
listData.Add(key, new List<flattenedList>());
}
listData[key].Add(f);
}
public class ClassA
{
public List<ClassB> classBList = new List<ClassB>();
public List<ClassC> classCList;
public int whatever;
public string something;
}
public class ClassB
{
public List<ClassC> classCList;
public int somethingElse;
public string otherThing;
}
public class ClassC
{
public int somethingA;
public string somethingB;
}
}
Note that I had to instantiate the classes in order to get the intellisense to let me type. I assume you'd create instance versions visible to this method either within class scope or within a public static class.
PS - if you don't need to maintain the origin of each datum (which class and list it came from), then there's an easier way to do this.