I have a class baseClass, and a list of objects of the baseClass. What i want to achieve is that i have to dynamically assign the instance number to each object in the list. for that what am doing is that use a constructor to do this.
Following is the class definition:
public class baseClass
{
private int _InstanceNumber;
private int _MyIntVal;
private string _MyString;
public string MyString
{
get { return _MyString; }
set { _MyString = value; }
}
public int MyIntVal
{
get { return _MyIntVal; }
set { _MyIntVal = value; }
}
public int MyProperty
{
get { return _InstanceNumber; }
}
public baseClass(int instance)
{
_InstanceNumber = instance;
}
}
The creation of the List of objects is as follows:
int instanceNumber = 0;
List<baseClass> classList = new List<baseClass>();
classList.Add(new baseClass(instanceNumber++) { MyString = "sample1", MyIntVal = 10 });
classList.Add(new baseClass(instanceNumber++) { MyString = "sample2", MyIntVal = 11 });
I know it is not the actual way for creating this. it does not give the index number actually. how can i calculate the instance number?
Consider the following scenario, that am creating another list of objects then it hard to maintain the instance number. or if i create another object(this also be an instance) external to the list.
int instanceNumber = 0;
List<baseClass> anotherClassList = new List<baseClass>();
classList.Add(new baseClass(instanceNumber++) { MyString = "sample1", MyIntVal = 10 });
classList.Add(new baseClass(instanceNumber++) { MyString = "sample2", MyIntVal = 11 });
Updates:
This is my temporary solution for this. i need proper way/ method to maintain instance number
If you want to find the index of item in the list, you should ask it from the list, not the item like:
var index = list.IndexOf(item);
But it seems that you expect the item to be aware of its position in the list. In order to do this, you should pass the list to the item so it can use it to find its own place in it:
public class Item
{
private List<Item> _containerList;
public Item(List<Item> containerList)
{
_containerList = containerList;
}
public int InstanceNumber
{
get { return _containerList.IndexOf(this); }
}
}
and change your code to:
List<Item> classList = new List<Item>();
classList.Add(new Item(classList ) { ... });
classList.Add(new Item(classList ) { ... });
Related
I am coding an application for my study, but i'm stuck at this point. I made a class called 'Neighborhood'. This class has a string and an int. In my main code I give the class a value and put it in a list. I now want to loop through my list and get the int out of it (put it in a listbox, or do a calculation). How do I get the int out of the list?
class Wijk
{
private string wijken;
private int tijd;
public string Wijken
{
get { return wijken; }
set { wijken = value; }
}
public int Tijd
{
get { return tijd; }
set { tijd = value; }
}
}
Created the list and the instance of the class.
List<object> Uden = new List<object>();
Wijk Wijkeninput = new Wijk();
Now I value the string and int with a combobox and textbox.
private void wijkAanmaken()
{
Wijkeninput.Wijken = Convert.ToString(cbWijken);
Wijkeninput.Tijd = Convert.ToInt16(tbSnelheid.Text);
Uden.Add(Wijkeninput);
}
For this, instead of having an object list, you can have list containing class objects like
List<Wjik> Uden = new List<Wjik>();
then you can access int as follows:
foreach (Wjik obj in listProgram)
{
int tij = Convert.ToInt32(obj.tijd);
}
First the List can be declared like this:
List<Wijk> Uden = new List<Wijk>();
To iterate over it:
foreach(var item in Uden)
{
var myInt = item.Tijd;
var myString = item.Wijken;
//here do whatever you want with the values
}
I want this method to work with any variable - i.e., passing a "Price" value to the method then getting the total price of all items.
private int GetTotalValue(int stat){
int total = 0;
foreach(Item i in Vendor.items){
totalStat += i.stat;
}
return total;
}
However, it has no way of knowing the name of the variable that I passed as the parameter, and thus no way of accessing it in other objects.
How would I tell the method what variable I'm passing, instead of just the value of it?
If you always want the sum of some property value you could encapsulate that logic into a method, e.g. GetVendorItemSum:
internal class Program
{
private static void Main(string[] args)
{
var items = new[] {
new Item {Price = 1},
new Item {Price = 2}
};
var vendor = new Vendor {Items = items};
var vendorSum = GetVendorItemsSum(vendor, x => x.Price);
}
private static int GetVendorItemsSum(Vendor vendor, Func<Item, int> func)
{
return vendor.Items.Sum(func);
}
}
public class Vendor
{
public IEnumerable<Item> Items;
}
public class Item
{
public int Price { get; set; }
}
I have the following class in Wpf
public class test
{
public int id;
public string name;
}
As well as two of the list of ObservableCollection types that I've made right
private ObservableCollection<Test> ClassTest;
private ObservableCollection<Test> TempClassTest;
public MainWindow()
{
InitializeComponent();
ClassTest = new ObservableCollection<Test>();
TempClassTest = new ObservableCollection<Test>();
ClassTest.Add(new Test() { id = 1, name = "T1" });
ClassTest.Add(new Test() { id = 2, name = "T2" });
ClassTest.Add(new Test() { id = 3, name = "T3" });
}
The problem is that whenever the test method is changed, it changes in the first variable like the following code:
private void Button_Click(object sender, RoutedEventArgs e)
{
TempClassTest = ClassTest;
TempClassTest[0].id = 1110;
}
Now the value of ClassTest[0] is id=1110
In C# - Read about reference types.
System.Collections.ObjectModel.ObservableCollection is a reference type. Following line of code:
TempClassTest = ClassTest;
Creates a shallow copy (it does not create entirly new member wise list).
The item in the Collection is also a ReferenceType, so you need to Deep Clone the item again.
Do something like:
public class Test: ICloneable
{
public int Id { get; set; }
public string Name { get; set; }
public object Clone()
{
return new Sample { Id = this.Id, Name = this.Name };
}
}
And then,
ObservableCollection<Test> coll1 = new ObservableCollection<Test>();
coll1.Add(new Test{ Id = 1 });
coll1.Add(new Test{ Id = 2 });
coll1.Add(new Test{ Id = 3 });
ObservableCollection<Test> coll2 = new ObservableCollection<Test>();
foreach (var item in coll1)
{
coll2.Add(item.Clone() as Test);
}
coll2[0].Id = 1500;
the first variable object is assigned to second variable. so, the first variable and second variable pointing the same memory address. so, you change any value of first or second it should effect on two variables.
You use clone
Copy Observable Collection
I'm trying to add strings to a List<string> so I can print them with a loop in a certain point of time, being more specific here is part of my code:
public class Foo{
public string propertyA;
public string propertyB;
public string propertyC;
public List<string> list;
Public Foo(){
list = new List<string>();
list.Add(propertyA);
list.Add(propertyB);
list.Add(propertyC);
}
}
In later code, after assigning propertyA and the other variables and trying to iterate over the List I get empty strings. I require the properties to be in the list. My questions is which would be the best way to achieve this?
Looks like you are getting empty strings because when you are adding to the list the values in your properties have not been set at the time that the Foo() constructor is called...
Try passing values and setting them in the Foo constructor as follows:
public class Foo{
public string propertyA;
public string propertyB;
public string propertyC;
public List<string> list;
Public Foo(string propA, string propB, string propC){
propertyA = propA;
propertyB = propB;
propertyC = propC;
list = new List<string>();
list.Add(propertyA);
list.Add(propertyB);
list.Add(propertyC);
}
}
Alternatively you could add the values to the list at a later time when the properties are actually set and not in the constructor e.g.
public string PropertyA
{
//set the person name
set { propertyA = value;
list.Add(value);
}
//get the person name
get { return propertyA; }
}
...
What you're seeing is expected behavior. Updating "propertyA", etc later on won't update the strings that have already been added to the collection.
You could consider using a Dictionary instead of your own class, and then adding and updating elements is easier: (and you don't have to keep updating your class with new property names)
var properties = new Dictionary<string, string>();
properties.Add("propertyA", "some value of property A");
properties["propertyA"] = "some new value";
And when you want to display the values later:
MessageBox.Show(string.Join(Environment.NewLine, properties));
Alternatively, if you want a class and the option of adding properties to it, then maybe extending the Dictionary class like this will at least make things easier to maintain, so you can add more properties that'll stay in sync with the underlying Dictionary, with a minimum of fuss.
public class PropertyCollection : Dictionary<string, string>
{
public string PropertyA
{
get { return GetValue(); }
set { StoreValue(value); }
}
public string PropertyB
{
get { return GetValue(); }
set { StoreValue(value); }
}
protected string GetValue([CallerMemberName] string propName = "")
{
if (ContainsKey(propName))
return this[propName];
return "";
}
protected void StoreValue(string propValue, [CallerMemberName] string propName = "")
{
if (ContainsKey(propName))
this[propName] = propValue;
else
Add(propName, propValue);
}
}
If you want to assign propertyA, B, C after an instance of Foo is created and enumerate them, you could try something like this:
public class Foo
{
public string propertyA { get { return list[0]; } set { list[0] = value; } }
public string propertyB { get { return list[1]; } set { list[1] = value; } }
public string propertyC { get { return list[2]; } set { list[2] = value; } }
public List<string> list = new List<string>() {"", "", ""};
}
For the reasons why the code behaves in a way you might not expect, see How are strings passed in .NET?
I have a class MySet
class MySet
{
.......
}
This class will declare a reference to another type
(i.e)
class MySubSet
{
....
}
The purpose of the type MySubset is to supply "subset id" and a collection of integers to
the type MySet.
Which one of the followings is the correct implementation
(1)
class MySet
{
int mySetID;
MySubSet subset = new MySubSet();
public int MySetID
{
get { return mySetID; }
set { mySetID = value; }
}
public MySubSet MySubSet
{
get { return subset; }
set { subset = value; }
}
}
class MySubSet
{
int subsetID;
List<int> subset = new List<int>();
public List<int> SubSet
{
get { return subset; }
set { subset = value; }
}
public int SubSetID
{
get { return subsetID; }
set { subsetID = value; }
}
}
(2)
class MySet
{
int mySetID;
AnotherSubSet subset = new AnotherSubSet();
public int MySetID
{
get { return mySetID; }
set { mySetID = value; }
}
public AnotherSubSet MySubSet
{
get { return subset; }
set { subset = value; }
}
}
class AnotherSubSet : List<int>
{
int subsetID;
List<int> lst = new List<int>();
public int SubSetID
{
get { return subsetID; }
set { subsetID = value; }
}
}
If both are worst design consideration help me to implement the one that I could follow.
MySet doesn't look like a collection to me. It's just a class.
I'd rename it to ´MyEntity´or something like that.
List<MyEntity> mySet = new List<MyEntity>();
From all the information you've provided, I would do this:
public class MyEntity
{
public int ID { get; set; } // shortcut
public List<int> Numbers = new List<int> { get; set; } // shortcut
}
Sorry, I don't have /Net3.0 to hand so can't check the constructor of the list with the shortcut get/set but its the theory that counts...
The first version is better (as improved upon by ck) - use composition instead of inheritance. You are advised not to add properties to collections, which is effectively what you're doing in version 2. Collections should contain their items only. Someone else may be able to expand on the reasons for this, as I am not an expert, but it does cause serialization problems.
Number 2 is better, use inheritence not composition for this pattern, - because fundementally, it is a collection. It does not contain a collection. Inheritance gives you all the functionality of the base class without the need to write pass-through functions. If you want to add a new item to the collection, using composition, you either have to add a pass through method for the Add() method to class MySubSet:
class MySubSet
{
int subsetID;
List<int> subset = new List<int>();
public List<int> SubSet
{
get { return subset; }
set { subset = value; }
}
public void Add(int i) { subset.Add(i); } // pass through to subset.Add()
}
or you have to use the following non-intuitive and confusing syntax...
MySet.MySubSet.SubSet.Add(67);
with inheritence, all you need is
MySet.MySubSet.Add(67);