private List<string> _S3 = new List<string>();
public string S3[int index]
{
get
{
return _S3[index];
}
}
Only problem is I get 13 errors. I want to call string temp = S3[0]; and get the string value from the list with the particular index.
You can't do that in C# - you can't have named indexers like that in C#. You can either have a named property, with no parameters, or you can have an indexer with parameters but no name.
Of course you can have a property with a name which returns a value with an indexer. For example, for a read-only view, you could use:
private readonly List<string> _S3 = new List<string>();
// You'll need to initialize this in your constructor, as
// _S3View = new ReadOnlyCollection<string>(_S3);
private readonly ReadOnlyCollection<string> _S3View;
// TODO: Document that this is read-only, and the circumstances under
// which the underlying collection will change
public IList<string> S3
{
get { return _S3View; }
}
That way the underlying collection is still read-only from the public point of view, but you can access an element using:
string name = foo.S3[10];
You could create a new ReadOnlyCollection<string> on each access to S3, but that seems a little pointless.
C# cannot have parameters for their properties. (Side note: VB.Net can though.)
You can try using a function instead:
public string GetS3Value(int index) {
return _S3[index];
}
You have to use this notation
public class Foo
{
public int this[int index]
{
get
{
return 0;
}
set
{
// use index and value to set the value somewhere.
}
}
}
_S3[i] should automatically return the string at position i
So just do:
string temp = _S3[0];
Try this
private List<string> _S3 = new List<string>();
public List<string> S3
{
get
{
return _S3;
}
}
I would just go with
class S3: List<string>{}
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 have been given some code that has objects composed of lists of different types. A simple example of what I mean:
public class Account
{
private long accountID;
private List<string> accountHolders;
private List<string> phoneNumbers;
private List<string> addresses;
public Account()
{
this.accountHolders = new List<string>();
this.phoneNumbers = new List<string>();
this.addresses = new List<string>();
}
public long AccountID
{
get
{
return this.accountID;
}
set
{
this.accountID = value;
}
}
}
For a requirement I need to get the total amount of elements in each list for validation purposes. I have the following method which works:
public class AccountParser
{
// Some code
public int CountElements(Account acct)
{
int count = 0;
count += acct.accountHolders.Count();
count += acct.phoneNumbers.Count();
count += acct.addresses.Count();
return count;
}
}
but was wondering if there was a better way to do this. I know I can enumerate over a List with Linq but I can't seem to get it to work in this case.
What you're doing is the right thing
You could do it in one line without declaring any variable
public int CountElements(Account acct)
{
return acct.accountHolders.Count() + acct.phoneNumbers.Count() + acct.addresses.Count();
}
But it doesn't change much.
The ammount of lists is static, because the class is static, so it doesn't make sense to use Reflection if the structure wont change.
Now you could have more than one Account classes with different types of lists. In that case, i would create an abstract AbsAccount class, that has an abstract CountElements property:
public abstract class AbsAccount
{
public abstract int CountElements { get; }
}
public class Account: AbsAccount
{
private List<string> accountHolders;
private List<string> phoneNumbers;
private List<string> addresses;
public override int CountElements
{
get
{
return this.accountHolders.Count()
+ this.phoneNumbers.Count()
+ this.addresses.Count();
}
}
}
public class AccountParser
{
// Some code
public int CountElements(AbsAccount acct)
{
return acct.CountElements;
}
}
But maybe im taking it too far...
You can add items to a list then call .Summethod on it, but it's not better from performance point of view.
public class AccountParser
{
// Some code
public int CountElements(Account acct)
{
List<string> all = new List<string>();
all.AddRange(acct.accountHolders);
all.AddRange(acct.phoneNumbers);
all.AddRange(acct.addresses);
return all.Count();
}
}
Another approach will be (because I can see you are not exposing directly your lists) to use observer pattern, and update the number of elements in another field or even list, every time you are updating one of your lists. Then get the value from that field, but I think the best way is the one you have already adopted.
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?
related to this topic:
https://stackoverflow.com/questions/15170054/context-hint-using-combobox
Is there a way I can use the strings in my separate class:
namespace KeyWord
{
public class KeyWord
{
//Definitions
public String[] keywords = { "abstract", "as", "etc." };
}
}
to mylistbox items in my mainform?
lb = new ListBox();
Controls.Add(lb);
ty in advance
Sure. Try something like this.
KeyWord kw = new KeyWord();
foreach (string str in kw.keywords)
{
lb.Items.Add(str);
}
Or you can use databinding.
Also, if all you're doing is getting an array of strings from that class, you might want to use a static property so you don't have to instantiate an instance of that object. I would recommend using properties either way for exposing public data, instead of a public field.
Here's an example of using a static property, instead:
public class KeyWord
{
// Private field, only accessible within this class
private static string[] _keywords = { "abstract", "as", "etc." };
// Public Static Property, accessible wherever
public static string[] Keywords
{
get { return _keywords; }
set { _keywords = value; }
}
}
Then:
foreach (string str in KeyWord.Keywords)
{
lb.Items.Add(str);
}
Notice, I didn't instantiate the class in this example (no new KeyWords())
I need to persist in Session some data.
I wrote many properties like that:
public List<string> FillOrder
{
get { return Session[SessionKeys.QueryFillOrder] as List<string> ?? new List<string>(); }
set { Session[SessionKeys.QueryFillOrder] = value; }
}
When I have to consume this data I have to write code like that:
List<string> fillOrder = FillOrder;
fillOrder.Add(accordion.ID);
FillOrder = fillOrder;
that seems to me so ugly, because I would prefer to do that:
FillOrder.Add(accordion.ID);
but this way my value would not be saved back in Session.
Can you think of any better way to achieve the same result?
Thank you very much!
I always use a wrapper class around the ASP.NET session to simplify access to session variables:
public class MySession
{
// private constructor
private MySession()
{
FillOrder = new List<string>();
}
// Gets the current session.
public static MySession Current
{
get
{
var session = (MySession)HttpContext.Current.Session["__MySession__"];
if (session == null)
{
session = new MySession();
HttpContext.Current.Session["__MySession__"] = session;
}
return session;
}
}
// **** add your session properties here, e.g like this:
public List<string> FillOrder {get; set; }
public string Property1 { get; set; }
public DateTime MyDate { get; set; }
public int LoginId { get; set; }
}
This class stores one instance of itself in the ASP.NET session and allows you to access your session properties in a type-safe way from any class, e.g like this:
MySession.Current.FillOrder.Add(accordion.ID);
int loginId = MySession.Current.LoginId;
string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;
DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;
This approach has several advantages:
you can initialize your session variables in the constructor (i.e. new List<string>)
it saves you from a lot of type-casting
you don't have to use hard-coded session keys throughout your application (e.g. Session["loginId"]
you can document your session items by adding XML doc comments on the properties of MySession
You can use an extension method as well, but I do think the example by M4N might be better:
EDIT made it a generic type
public static class Extensions
{
public static void AddWithSession<T>(this List<T> list, T value, string key)
{
list.Add(value);
HttpContext.Current.Session[key] = list;
}
}
str.AddWithSession(accordion.ID,SessionKeys.QueryFillOrder);
You could write an own class that implements ICollection or IList, there you would implement Add as Session[...] = ...
Using a single class for all Session variables as suggested by #M4N is a good idea, though it risks becoming a "God" class (in which case you could partition into several classes implemented in this way).
However you could just change your property implemetation as follows:
public List<string> FillOrder
{
get
{
List<string> result = Session[SessionKeys.QueryFillOrder] as List<string>;
if (result == null)
{
result = new List<string>();
Session[SessionKeys.QueryFillOrder] = result;
}
return result;
}
set { Session[SessionKeys.QueryFillOrder] = value; }
}
In this example, you probably don't want a setter.