How to get the name of the list - c#

I create a list first
List<String> dummy1 = new List<String>();
List<String> dummy2 = new List<String>();
List<String> dummy3 = new List<String>();
List<String> dummy4 = new List<String>();
Before I add the list to Dictionary
Dictionary<int, List<String>> _d = new Dictionary<int, List<String>>()
{
{1, dummy1},
{2, dummy2},
{3, dummy3},
{4, dummy4},
};
then I want to have the name of the list by looping the key
foreach (var key in _d.Keys)
{
MessageBox.Show(_d[key].GetType().Name);
}
but the output is list 1, I want to get the
dummy1
dummy2
dummy3
dummy4

As I commented, you can only do this with really funky syntax. Here's an example of what I mean
void Main()
{
List<String> dummy1 = new List<String>();
List<String> dummy2 = new List<String>();
List<String> dummy3 = new List<String>();
List<String> dummy4 = new List<String>();
var _d = new Dictionary<int, Expression<Func<List<String>>>>()
{
{1, () => dummy1},
{2, () => dummy2},
{3, () => dummy3},
{4, () => dummy4},
};
foreach(var kvp in _d)
{
MessageBox.Show(kvp.Value.nameof());
}
}
// Define other methods and classes here
public static class TestExtension
{
public static String nameof<T>(this Expression<Func<T>> accessor)
{
return nameof(accessor.Body);
}
public static String nameof<T, TT>(this T obj, Expression<Func<T, TT>> propertyAccessor)
{
return nameof(propertyAccessor.Body);
}
private static String nameof(Expression expression)
{
if (expression.NodeType == ExpressionType.MemberAccess)
{
var memberExpression = expression as MemberExpression;
if (memberExpression == null)
return null;
return memberExpression.Member.Name;
}
return null;
}
}
The main issue is that you need the dictionary to store an expression, rather than a List
Secondly, to actually ACCESS the list, you need to do this:
var list = _d[1].Compile()();
And lastly, if dummy1 ever gets reassigned, you'll lose the reference to the list you're expecting.
In short, it's very unlikely that you need to do this. It's rare that the variable names in code should actually affect behaviour.

You are assigning data to a variable name and you are going to get the variable name in order to access the data. I would create a simple object with a Name and List and add it to the Dictionary.

Just make a custom class that inherits from List<string> and have a Name property.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
MyList dummy1 = new MyList("dummy1");
MyList dummy2 = new MyList("dummy2");
MyList dummy3 = new MyList("dummy3");
MyList dummy4 = new MyList("dummy4");
Dictionary<int, MyList> _d = new Dictionary<int, MyList>()
{
{1, dummy1},
{2, dummy2},
{3, dummy3},
{4, dummy4},
};
foreach (var key in _d.Keys)
{
Console.WriteLine(_d[key].Name);
}
}
}
public class MyList : List<String>
{
private string name;
public string Name
{
get
{
return name;
}
}
public MyList(string name)
{
this.name = name;
}
}
Results:
dummy1
dummy2
dummy3
dummy4
Demo

Instead of creating a Dictionary that stores an int and a list:
Dictionary<int, List<String>>
Create a Dictionary that stores the name of the list with the list:
Dictionary<string, List<String>>
If you want to then get the int number that corresponds to the list, you can use a normal for loop and see what value is at the location when let's say i = 1.

Related

Can you get a value in a structure through an outside variable in C#?

So, I am kind of used to structuring things like JavaScript and in light of that I do struggle in some areas in C#. Right now I'm trying to use structures in a way I can call a value using a variable that would match the value I'm going for.
For example my structure would be this:
public struct test
{
public int[] valuesOne;
public int[] valuesTwo;
public test(int[] data)
{
valuesOne = new int[2] { data[0], data[1] };
valuesTwo = new int[2] { data[2], data[3] };
}
}
Okay so say I have all of this and I want to get test.valuesOne[0] but from a variable like so:
string getValue = "valuesOne";
Console.Log(test[getValue][0]);
I know this provides a indexing error, but I'm in a situation where I kind of want this functionality. Sure I can pass my structure through a simple method, but if I can do it in a similar way to this without a huge problem I'd like to.
c# and JavaScript are two different pairs of shoes.
I try to do something similar as your code, however not sure if that's what you're looking for.
class Program
{
static void Main(string[] args)
{
var t = new Test(new int[] { 1, 2, 3, 4 });
var value = t["valueOne"][0];
Console.WriteLine(value);
}
}
public class Test
{
private Dictionary<string, int[]> _data = new Dictionary<string, int[]>();
public Test(int[] data)
{
_data.Add("valueOne", new int[] { data[0], data[1]});
_data.Add("valueTwo", new int[] { data[2], data[3]});
}
public int[] this [string value]
{
get { return _data[value]; }
}
}
you can use dynamic + reflection + this[string key] to do it. but it needs some extra code.
note :
it's a bad idea,this will lose the advantage of strong type checking.
demo :
void Main()
{
var test = new test(new[] {1,2,3,4,5});
Console.WriteLine( test["valuesOne"][0] ); //1
Console.WriteLine( test["valuesTwo"][1] ); //4
}
public struct test
{
public int[] valuesOne;
public int[] valuesTwo;
public test(int[] data)
{
valuesOne = new int[2] { data[0], data[1] };
valuesTwo = new int[2] { data[2], data[3] };
}
public dynamic this[string key]
{
get
{
return this.GetFieldValue(key);
}
}
}
public static class Extension
{
public static object GetFieldValue(this object t, string fieldName)
{
var type = t.GetType();
var fields = type.GetFields();
var field = fields.Single(pi => pi.Name == fieldName);
return field.GetValue(t);
}
}
online demo link : can-you-get-a-value-in-a-structure-through-an-outside-variable-in-c | .NET Fiddle
Usually I too would recommend using a Dictionary as in #gsharp's answer. But since that isn't an option for you, perhaps you could go with a Dictionary of delegates instead:
var accessor = new Dictionary<string, Func<test, int[]>>
{
{ nameof(test.valuesOne), x => x.valuesOne },
{ nameof(test.valuesTwo), x => x.valuesTwo }
};
Now you can access your data like so:
string getValue = "valuesOne";
Console.Log(accessor[getValue](test_instance)[0]);
You can extend this concept by wrapping this Dictionary into an Extension Method:
public static class Extensions
{
private static new Dictionary<string, Func<test, int[]>> accessor =
new Dictionary<string, Func<test, int[]>>
{
{ nameof(test.valuesOne), x => x.valuesOne },
{ nameof(test.valuesTwo), x => x.valuesTwo }
};
public static int[] Property(this test t, string name)
{
return accessor[name](t);
}
}
Then you can write:
Console.Log(test_instance.Property(getValue)[0]);

Returning integer and string

I have a function as follow. I need to return two parameters. First the index that is as list and it is done by the function. The other parameter that I need to return is a string str.
What would be your best suggestion for these outputs? a list with two different parameters? or what? Please let me know your ideas! Thanks
public List<int> index_selexted(TreeNodeCollection treeView, List<int> list)
{
List<int, List<string>> output_typ = new List<int, >();
foreach (TreeNode node in treeView)
{
if (node.Checked)
{
list.Add(node.Index);
string str = Regex.Match(node.Text, #" \((.*?)\) ").Groups[1].Value;
}
else
{
index_selexted(node.Nodes, list);
}
}
return list;
}
Well, since TreeNode.Index is not unique within the entire TreeNodeCollection then Dictionary<int, String> is not a choice, but Dictionary<int, List<String>> will do
//TODO: find a better name for dict
public Dictionary<int, List<String>> index_selexted(
TreeNodeCollection treeView,
Dictionary<int, List<String>> dict == null) { // == null for autocreation
if (null == treeView)
throw new ArgumentNullException("treeView");
if (null == dict)
dict = new Dictionary<int, List<String>>();
foreach (TreeNode node in treeView)
if (node.Checked) {
String match = Regex.Match(node.Text, #" \((.*?)\) ").Groups[1].Value;
List<String> list;
if (dict.TryGetValue(node.Index, out list))
list.Add(match);
else
dict.Add(node.Index, new List<String>() {match});
}
else
index_selexted(node.Nodes, dict);
return dict;
}
And so you'll have something like this as an output: index + all matches for it:
{1, ["abc", "def", "gh"]}
{3, ["xyz"]}
I've added dict == null in order to make the call easier:
// You don't have to pre-create the dictionary
var myDict = index_selexted(myTreeView.Nodes);
Use a Tuple
var res = new Tuple<string, List<string>>("string1", new List<string>());
You could either do
public class IndexSelectionResult{
public List<something> Index{get;set;}
public String StringResult
}
and return an instance of that, OR, if you're lazy, you can return a TUPLE:
public Tuple<List<string>, string>> myFunction(){ /* code */}
I believe you want this:
public static List<int> index_selexted(TreeNodeCollection treeView, out string str)
{
str = null;
var list = new List<int>();
var output_typ = new List<int>();
foreach (TreeNode node in treeView)
{
if (node.Checked)
{
list.Add(node.Index);
str = Regex.Match(node.Text, #" \((.*?)\) ").Groups[1].Value;
}
else
{
index_selexted(node.Nodes, list);
}
}
return list;
}
usage as such:
var treeview = sometreeview;
string output;
var result = index_selected(treeview, out output);
Console.WriteLine(output);
instead of using the list in your example (List> output_typ = new List();) consider
using a dictionary:
var output_typ = new Dictionary<int, List<string>>();
or a list of tuples:
var output_typ = new List<Tuple<int, List<string>>();
Hope this helps
There are a lot of ways to do this in fact, it depends on your specific use case which one you'd prefer.
Using a class
class MyResult {
public List<int> MyList { get; set; }
public string MyString { get; set; }
}
public MyResult index_selected(arg1..., arg2...) {
return new MyResult {
MyList = outputList,
MyString = "outputString"
}
}
Using a class is my preferred way. Though it may clutter if you have many return types it is by far the most readable solution.
Using a tuple
public Tuple<List<int>, string> index_selected(arg1..., arg2...) {
return Tuple.Create(outputList, "outputString");
}
My second goto option is a tuple. It is a lot more difficult to determine what the values contained in the tuple represent. But doesn't require creating more classes and is a quick solution (I use it mostly for private methods where readability is not much of a concern).
Using the out keyword
public List<int> index_selected(arg1..., out string resultString) {
resultString = null;
/* Doing calculations and such */
resultString = "
return outputList;
}
In this case the string passed to the resultString parameter will be replaced by whatever you assign to it in the method (see out keyword). Depending on your use case you may also want to look at the ref keyword.
This approach is rather error prone and is generally not preffered.

C# Equivalent to Java's Double Brace Initialization?

Expected code in C# (that Java has)
List<String> myList = new List<String>() {{
add("Hello");
add("World!");
}}
// myList = [ "Hello", "World" ]
Just wondering if there is an equivalent, possibly with C#'s static constructors?
EDIT:
To clarify this isn't explicitly for Collections but for any class structure.
For example:
abstract class myClass {
String data;
List<String> list;
void setupList() {
list = new List<String>();
}
}
...
var obj = new myClass() {{
data = "Yo";
setupList();
}};
You're looking for the collection initializer syntax:
List<String> myList = new List<String>() {"Hello","World!"};
This is an object initializer that also uses collection initializers (note the type inference in the collection initializers, the List that is created is of type List) :
var myClass = new MyClass{
Data = "foo",
List = new List{"item1", "item2"},
IntArray = new[]{1,2,3},
Dictionary = new Dictionary<string,string>{{"key1","value1"},{"key2","value2"}},
};
You can't call arbitrary methods like SetupList() in an initializer, instead you would initialize the List property the first time it is accessed or statically, etc.
You can use the Lazy class or implement it yourself like so (?? is the null coalescing operator):
class MyClass{
public string Data { get; set; }
private IList<string> _list0 = new List();
public IList<string> List0
{
get
{
return _list0;
}
}
private IList<string> _list1;
public IList<string> List1
{
get
{
return _list1 ?? (_list1 = new List());
}
}
private readonly Lazy<IList<string>> _lazyList = new Lazy<IList<string>>(() => new List<string>());
public IList<string> List2
{
get
{
return _lazyList.Value;
}
}
}
This is how you can add items to a list of strings
List<string> myList = new List<string>();
myList.Add("Hello");
myList.Add("World!");
And if you want to remove them you can simply do this
myList.Remove("Hello");
myList.Remove("World!");

How to Add an item to ArrayList and Dictionary using reflection

public class MyClass
{
public MyClass()
{
myDictionary = new Dictionary<string, string>();
myArray = new List<int>();
}
private Dictionary<string, string> myDictionary;
public Dictionary<string, string> MyDictionary
{
get { return myDictionary; }
}
private List<int> myArray;
public List<int> MyArray
{
get { return myArray; }
}
}
static void Main(string[] args)
{
var model = new MyClass();
Type t = model.GetType();
System.Reflection.PropertyInfo[] properties = t.GetProperties();
//Add items to MyArray and MyDictionary in this model According to the properties using reflection
}
I want to add items to MyArray and MyDictionary in this model According to the properties using reflection.
Thank you for your help !
var dictProp = properties.Single(t => t.Name = "MyDictionary");
var myDict = (Dictionary<string,string>)dictProp.GetValue(model, null);
myDict.Add("MyKey", "MyValue");
To add an Item to a Generic.List<T> you use the Add method
Example:
MyArray.Add(1);
For Generic.Dictonary<T> you also use the Add method, but supply 2 values, Key and Value
MyDictionary.Add("MyKey", "MyValue");
So you can just loop though your PropertyInfo[] and add whatever you need to your List<T> or Dictionary<T>
foreach(var prop in properties )
{
MyArray.Add(a number from somewhere);
MyDictionary("some key", "some value");
}

copy dictionary containing object to an array of objects c#

I have a Dictionary like Dictionary<string,Object>,is there any method of converting the Dictionary to an array of objects,where the class of the object will contain two members-one of which will be the string and the other will be the Object stored as the value-pair in the dictionary.Please help!!!..
Dictionary<TKey, TValue> implements IEnumerable<T> where T is KeyValuePair<TKey, TValue>. To flatten this to an array all that is necessary is to call IEnuemrable<T>.ToArray as such:
Dictionary<string, int> dict = new Dictionary<string, int>() { { "Key1", 0 }, { "Key2", 1 } };
var kvArray = dict.ToArray();
kvArray will then be an array objects that reference the keys and values of each element in dict as two separate members of the same object.
Your question is a bit ambiguous though, perhaps further explanation would help us figure out a more appropriate solution.
Re your comment, LINQ is good for that:
Dictionary<string, int[]> dict = new Dictionary<string, int[]>() { { "Key1", new int[] { 0, 1, 2 } }, { "Key2", new int[] { 4, 5, 6 } } };
var pairs = dict.SelectMany(pair => pair.Value
.Select(v =>
new {
Key = pair.Key,
Value = v
}
)
);
Given a class:
class ClassA
{
string CustomerId { get; set; }
PatientRecords[] Records { get; set; }
public ClassA(string name, PatientRecords[] records)
{
Name = name;
Records = records;
}
}
I'm assuming that CollectionOfPatientRecords implements IEnumberable:
var dict = new Dictionary<string, CollectionOfPatientRecords> ( ... );
Then to get your array of ClassA with the right values:
dict.Select(kv => new ClassA(kv.Key, kv.Value.ToArray())).ToArray();

Categories