Reputation:
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;
}
Upvotes: 1
Views: 114
Reputation: 60
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.
Upvotes: 0
Reputation: 19903
Use a Tuple
var res = new Tuple<string, List<string>>("string1", new List<string>());
Upvotes: 1
Reputation: 315
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
Upvotes: 0
Reputation: 186668
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);
Upvotes: 2
Reputation: 3222
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 */}
Upvotes: 0