The following lists are created in class named "Entities" and they are private.
I would like to return them (and use in another class)what I can do by :
public List<string> getCMList()
{
return exceptionsCM;
}
But if there is 10 list, I have to write a public "get" method for all of them. Is it possible to write a method, that takes a string as an input, and returns that list ?
Should be something similar to ..
public List<string> getList(.....)
{
return exceptionCM;
} //if we call getList(exceptionCM).
exceptionsCM = new List<string>();
exceptionsCM.Add("CM12");
exceptionsCM.Add("CM701");
exceptionsCM.Add("CM901/CM30");
exceptionsCM.Add("CM901K");
exceptionsCM.Add("CM1101");
exceptionsCM.Add("CM1101K");
//List with Multi Mill exceptions, they are included in the new MultiB
exceptionsMultiB = new List<string>();
exceptionsMultiB.Add("Multi650/450");
exceptionsMultiB.Add("Multi660/630");
exceptionsMultiB.Add("Multi650/800");
exceptionsMultiB.Add("Multi650/1000");
//List with Multi Mill exceptions, they are included in the new Multi01
exceptionsMulti01 = new List<string>();
exceptionsMulti01.Add("Multi301");
exceptionsMulti01.Add("Multi601");
exceptionsMulti01.Add("Multi801");
exceptionsMulti01.Add("Multi1001");
You could put them all in a static Dictionary> like that
Dictionary<string, List<string>> ListstDict = new Dictionary<string, List<string>>();
ListsDict.Add("exceptionsCM", exceptionsCM);
...
Then you could write a method like so:
public List<string> GetList(string name)
{
return ListsDict.ContainsKey(name) ? ListsDict[name] : null;
}
But then again, what's the point of this lists being private if you can get them that simply? It would be easier to just declare them as public properties with private setter
public List<string> exceptionsCM { get; private set; }
You can use a Dictionary<K,V> class for this
private Dictionary<string, List<<string>> dictionary =
new Dictionary<string, List<<string>>();
//fill that dictionary
...
//get list from a dictionary by list id
public List getList(string listId)
{
return dictionary[listId];
}
You can put all your lists in a dictionary:
// your code here
dictionary = new Dictionary<string, List<string>>();
dictionary.Add("exceptionsCM", exceptionsCM);
Then the getList method is as simple as:
public List<string> getList(string name)
{
return dictionary[name];
}
Use dictionary and enum.
Using enum for list keys instead of a string makes your code more robust for key renamings. I.e. when you rename MultiB to MultiB1 in Entities class then compiler would not show any errors and warnings about calls to GetList("MultiB"). In case of using enum compiler would show you these errors.
internal class Entities
{
private Dictionary<ListKey, List<string>> _liststDict =
new Dictionary<ListKey, List<string>>
{
{ListKey.Cm, new List<string> {"CM12", "CM701", "CM901/CM30", "CM901K", "CM1101", "CM1101K"}},
{ListKey.MultiB, new List<string> {"Multi650/450", "Multi660/630", "Multi650/800", "Multi650/1000"}},
{ListKey.Multi01, new List<string> {"Multi301", "Multi601", "Multi801", "Multi1001"}}
};
public List<string> GetList(ListKey key)
{
return _liststDict[key];
}
internal enum ListKey
{
Cm,
MultiB,
Multi01
}
}
internal class EntitiesTester
{
public static void Do()
{
Entities entities = new Entities();
Console.Out.WriteLine("CM count = {0}", entities.GetList(Entities.ListKey.Cm).Count);
Console.Out.WriteLine("MultiB count = {0}", entities.GetList(Entities.ListKey.MultiB).Count);
Console.Out.WriteLine("Multi01 count = {0}", entities.GetList(Entities.ListKey.Multi01).Count);
}
}
Related
I want to create "list of list of list". It should be:
Group (has a list of Members)
Member (has a Name and list of Properties)
Property (has Name and Value)
What I want is to have a possibility to add Property into Member (specified by its name) inside defined Group. Someting like this:
membersgroup.AddNewMember(memberXYZ);
...
membersgroup.memberXYZ.AddProperty(nameXYZ, valueXYZ).
I have trouble achieving this using list... I found class Hashable, but I am not sure if this is usable... and cannot make it works too...
Thank for any suggestion :)
Well, I suggest you create a custom class instead of your approach. But otherwise you can use a Dictionary.
var properties = new Dictionary<string, string>();
properties.Add("Prop1", "Value");
var members = new Dictionary<string, Dictionary<string, string>>();
members.Add("Member1", properties);
var group = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
group.Add("GroupName", members);
public class Group
{
public Group()
{
Members = new List<Member>();
}
public IEnumerable<Member> Members { get; set; }
}
public class Member
{
public Member()
{
Properties = new Dictionary<string, string>();
}
public string Name { get; set; }
IDictionary<string, string> Properties { get; set; }
}
The dictionary can take a key and a value, and the key should be unique.
You can also create a class property if you want to add another thing beside the name and the value
I would use indexers.
Here's a partial implementation:
class Group
{
private List<Member> _members;
public string this
{
get
{
return _members.Find(m => m.Name == value);
}
// You can also implement set here if you want...
}
}
class Member
{
private List<Property> _properties;
public string Name {get;set;}
public string this
{
get
{
return _properties.Find(m => m.Name == value);
}
}
}
class Property
{
public string Name {get;set;}
public string Value {get;set;}
}
And the usage:
var g = new Group();
g[memberName][propertyName].Value = someValue;
Note: This implementation is partial! it still needs constructor logic and any other logic you might need.
Likely the best solution is to use the C# class Dictionary - as suggested by zetawars, or a custom class - as suggested by Zohar Peled, or some mix of the two - as suggested by gandalf.
However, in order to use syntax similar to what is requested in the question...
membersgroup.AddNewMember(memberXYZ);
...
membersgroup.memberXYZ.AddProperty(nameXYZ, valueXYZ).
You can abuse ExpandoObject and Action, and do something awesome like this:
dynamic membersgroup = new ExpandoObject();
var getNewMemberObject = new Func<dynamic>(() =>
{
dynamic memberObject = new ExpandoObject();
var addPropertyAction = new Action<string, string>((propertyName, propertyValue) =>
{
((IDictionary<string, object>)memberObject).Add(propertyName, propertyValue);
});
memberObject.AddProperty = addPropertyAction;
return memberObject;
});
var addNewMemberAction = new Action<string>((memberName) =>
{
((IDictionary<string, object>)membersgroup).Add(memberName, getNewMemberObject());
});
membersgroup.AddNewMember = addNewMemberAction;
string memberXYZ = nameof(memberXYZ);
string nameXYZ = nameof(nameXYZ);
string valueXYZ = nameof(valueXYZ);
// look we did it!
membersgroup.AddNewMember(memberXYZ);
membersgroup.memberXYZ.AddProperty(nameXYZ, valueXYZ);
// and it actually works
var actualValue = membersgroup.memberXYZ.nameXYZ;
Console.WriteLine(actualValue); // "valueXYZ"
(for science of course)
How can we create a list of objects in C# and acces them by a specific field inside this object?
For example take this object:
class Section
{
public string Name { get; }
public long Size { get; }
public Section(string name, long size)
{
Name = name;
Size = size;
}
}
I would like to create a list of these objects which I can access by Section.Name.
I can create a dictionary like:
private static readonly Dictionary<string, Section> validSections = new Dictionary<string, Section>
{
{ "section-a", new Section("section-a", 1) },
{ "section-b", new Section("section-b", 2) },
{ "section-c", new Section("section-c", 3) },
{ "section-d", new Section("section-d", 4) },
};
But as you see, I have to declare the section name twice, which looks inelegant. Is there a more elegant way?
But as you see, I have to declare the section name twice, which looks
inelegant. Is there a more elegant way?
To avoid repetitve typing you can create dictionary from collection of sections via ToDictionary call:
private static readonly Dictionary<string, Section> validSections = new[] {
new Section("section-a", 1),
new Section("section-b", 2),
new Section("section-c", 3),
new Section("section-d", 4)
}.ToDictionary(s => s.Name);
If this is not time critical then you can use List<Section> list = new ArrayList<Section>(); and store data in it.
Later you can use LINQ to query based on name .where(x=>x.Name=="somename")
First of all your Model class can look like:
class Section
{
public string Name { get; set; }
public long Size { get; set; }
}
You don't need the Name twice so you can just create a list:
private static List<Section> myList = new List<Section>();
myList.add(new Section {Name = "section-a", Size = 1});
// do this for all the sections ...
Then as other answers suggest you can use LINQ:
myList.Single(s => s.Name == "section-a");
Will simply return the single element where the name is "section-a".
Read more about LINQ here: https://msdn.microsoft.com/en-us/library/bb308959.aspx
You could write a function that takes a list of sections and returns the corresponding dictionary. Something like:
public static Dictionary<string, Section> SectionDictionary(List<Section> sections) {
var dict = new Dictionary<string, Section>();
foreach (var section in sections)
dict.Add(section.Name, section);
return dict;
}
You can just access the elements using LINQ:
var list = ...;
var el = list.FirstOrDefault(o => o.Name = nameValue);
Or you can create a (collection) class that implements your own indexer / getter logic. E.g. (pseudocode)
public class MyCollection : Collection<Section>
{
public Section this[string nameValue]
{
get
{
return this.FirstOrDefault(o => o.Name == nameValue);
}
}
}
Then the usage is:
var coll = new MyCollection() ....;
var el = coll["Some name"];
trying to return 2 List values from a single function
I am using this code:-
public KeyValuePair<int, int> encrypt(string password)
{
List<int> key = new List<int>();
List<int> code = new List<int>();
/*
do stuff, do some more stuff and go!
*/
return new KeyValuePair<List<int>,List<int>>(key,code);
}
here I am trying to return 2 List<int> values but error occurs. How to return 2 list values from a single function
UPDATE
the answer is found, we got 2 correct answers thats why i didn't just pick one cause both work great
answer by HadiRj
answer by Enigmativity
and if you want to use my code then, this is the correct version of it:-
public KeyValuePair<List<int>, List<int>> encrypt(string password)
{
List<int> key = new List<int>();
List<int> code = new List<int>();
/*
do stuff, do some more stuff and go!
*/
return new KeyValuePair<List<int>,List<int>>(key,code);
}
A fairly neat way to go in this case is to use out parameters.
public void encrypt(string password, out List<int> key, out List<int> code)
{
key = new List<int>();
code = new List<int>();
/*
do stuff, do some more stuff and go!
*/
}
Change your function deceleration to
public KeyValuePair<List<int>, List<int>> encrypt(string password)
P.S: I'm not recommending this! Creating new class is better idea to handle your problem
way 1: Tuple:
public Tuple<List<int>, List<int>> func()
{
List<int> key = new List<int>() { 2,34,5};
List<int> code = new List<int>() { 345,67,7};
return Tuple.Create<List<int>,List<int>>(key, code);
}
way 2:
viewmodel
public class retViewModel
{
public List<int> key { get; set; }
public List<int> code { get; set; }
}
public retViewModel func()
{
List<int> key = new List<int>() { 2,34,5};
List<int> code = new List<int>() { 345,67,7};
retViewModel obj = new retViewModel() {
code=code,
key=key
};
return obj;
}
You can always return a List<List<int>>. From what I can see from your code the only reason why you use the KVP is because you know you are going to have two lists returned. Then I would say create another object that you can have the key and the code in it:
public class EncryptionResult
{
public IList<int> Key {get; set;}
public IList<int> Code {get; set;}
}
I don't recommend you going with the out/ref solution that some other comments suggest. It is not a good practice use them to return several parameters and they should be avoided. Also if you come to extend/modify that object at any point in time because you require more different data you don't need to change the signature of your interface however you need to modify every method and the caller if you change the parameters needed (including all your tests).
Very Simple
[WebMethod]
public static List<Teacher>[] BindData()
{
List<Teacher> list1 = new List<Teacher>();
List<Teacher> list2 = new List<Teacher>();
return new List<Teacher>[] { list1, list2 };
}
Note: Both list will use same class as i used Teacher class in both list.
List<int> key;
List<int> code;
static void Main(string[] args)
{
key = new List<int>();
code = new List<int>();
encrypt("",ref key,ref code);
}
public void encrypt(string password, ref List<int> key, ref List<int> code)
{
/*
do stuff, do some more stuff and go!
*/
}
Is there a List<> similar to a two dimension array? For each entry there is a number and text.
You can use Dictionary<int,String>
Sample:
Dictionary<int,string> samp = new Dictionary<int,string>();
dictionary.Add(1, "text1");
dictionary.Add(2, "text2");
Or, have a custom class which defines your requirement
public class Sample
{
public int Number;
public string Text;
}
Sample:
List<Sample> req = new List<Sample>();
Sample samObj = new Sample();
samObj.Number = 1;
samObj.Text = "FirstText";
req.Add(samObj);
There are many options, I describe some of them for you
use Dictionary<int, string>
Pros: very fast lookup
Cons: you can not have two string with same number, you don't have a List
var list2d = new Dictionary<int, string>();
list2d[1] = "hello";
list2d[2] = "world!";
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Key, item.Value);
}
use Tuple<int, string>
Pros: very simple and handy tool, you have a List
Cons: Tuples are immutable, you can not change their values once you create them, reduces code readability (Item1, Item2)
var list2d = new List<Tuple<int, string>>();
list2d.Add(new Tuple(1, "hello"));
list2d.Add(Tuple.Create(1, "world");
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Item1, item.Item2);
}
use a defined class,
Pros: you have a List, very customizable
Cons: you should write more code to setup
public class MyClass
{
public int Number { get; set; }
public string Text { get; set; }
}
var list2d = new List<MyClass>();
list2d.Add(new MyClass() { Number = 1, Text = "hello" });
list2d.Add(new MyClass { Number = 2, Text = "world" });
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Number, item.Text);
}
Custom class or dictionary are good options, you can also use the Tuple generic...
var i = new List<Tuple<int, string>>();
Dictionary requires that whatever value is used as key must be unique. So not ideal without uniqueness.
A custom class is preferable if you don't mind a little more code and gives you scope to extend later on if you decide you want other data in there.
Tuple is quick and easy but you lose readability and objects can not be edited.
Define a class wih a string and an int property
public class MyClass
{
public string MyStr {get;set;}
public int MyInt {get;set;}
}
then create a list of this class
List<Myclass> myList = new List<MyClass>();
myList.add(new MyClass{MyStr = "this is a string", MyInt=5});
Hope it will help
public class DATA
{
public int number;
public string text;
}
List<DATA> list = new List<DATA>();
How can I store data from 2 columns (from a database) in a List
List<string> _items = new List<string>();
Any help is appreciated
You create a class that will represent a row with 2 columns:
public class Foo
{
// obviously you find meaningful names of the 2 properties
public string Column1 { get; set; }
public string Column2 { get; set; }
}
and then you store in a List<Foo>:
List<Foo> _items = new List<Foo>();
_items.Add(new Foo { Column1 = "bar", Column2 = "baz" });
Use a tuple struct like KeyValuePair
List<KeyValuePair<string, string>> _items = new List<KeyValuePair<string, string>>();
_items.Add(new KeyValuePair<string, string>(foo, bar));
I would use a class
List<MyDataClass> _items = new List<MyDataClass>();
public class MyDataClass
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
You can either create a new class to hold the data, Or you could use the built in Tuple<> class. http://msdn.microsoft.com/en-us/library/system.tuple.aspx
Also if one of the columns contains a unique ID of some sort, you could also consider using a Dictionary<>.
It's about how to retrieve the data from the new two columns list
List<ListTwoColumns> JobIDAndJobName = new List<ListTwoColumns>();
for (int index = 0; index < JobIDAndJobName.Count;index++)
{
ListTwoColumns List = JobIDAndJobName[index];
if (List.Text == this.cbJob.Text)
{
JobID = List.ID;
}
}
I know this question is pretty old and by now you probably got your answer and have figured out what you need but I wanted to add something that might help someone in the future.
The best current answer is frankly from #csharptest.net but it has a serious performance drawback and so here is my approach a la his answer based on a suggestion to use Dictionary<TKey, TValue>
private Dictionary<string, string> _items = new Dictionary<string, string>();
// if you need to check to see if it exists already or not
private void AddToList(string one, string two)
{
if (!_items.ContainsKey(one))
_items.Add(one, two);
}
// you can simplify the add further
private void AddToList(string one, string two)
{
_items[one] = two;
// note if you try to add and it exists, it will throw exception,
// so alternatively you can wrap it in try/catch - dealer's choice
}
you can also make array of list
List<string> [] list= new List<String> [];
list[0]=new List<string>();
list[1]=new List<string>();
list[0].add("hello");
list[1].add("world");
You could do this:
List<IList<string>> cols = new List<IList<string>>();
You can set how many columns you want.
cols.Add(new List<string> { "", "", "","more","more","more","more","..." });