61

I need a two column list like:

List<int,string> mylist= new List<int,string>();

it says

using the generic type System.collection.generic.List<T> requires 1 type arguments.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Benny Ae
  • 1,897
  • 7
  • 25
  • 37

9 Answers9

83

Depending on your needs, you have a few options here.

If you don't need to do key/value lookups and want to stick with a List<>, you can make use of Tuple<int, string>:

List<Tuple<int, string>> mylist = new List<Tuple<int, string>>();

// add an item
mylist.Add(new Tuple<int, string>(someInt, someString));

If you do want key/value lookups, you could move towards a Dictionary<int, string>:

Dictionary<int, string> mydict = new Dictionary<int, string>();

// add an item
mydict.Add(someInt, someString);
newfurniturey
  • 37,556
  • 9
  • 94
  • 102
  • 2
    With the `Tuple<,>`, it is a bit easier to write `mylist.Add(Tuple.Create(someInt, someString));`. – Jeppe Stig Nielsen Oct 07 '13 at 18:43
  • @JeppeStigNielsen That's a personal preference; `Tuple.Create(t1, t2)` is functionally equivelant to `new Tuple(t1, t2)` and I, personally, prefer writing and reading the latter as it's more explicit. I don't argue that it's more work - but I like seeing exactly what's required =P – newfurniturey Oct 07 '13 at 18:46
  • There is also `SortedDictionary` or `SortedList`, but it depends on his use. – Jeppe Stig Nielsen Oct 07 '13 at 18:47
49

You could use an immutable struct

public struct Data
{
    public Data(int intValue, string strValue)
    {
        IntegerData = intValue;
        StringData = strValue;
    }

    public int IntegerData { get; private set; }
    public string StringData { get; private set; }
}

var list = new List<Data>();

Or a KeyValuePair<int, string>

using Data = System.Collections.Generic.KeyValuePair<int, string>
...
var list = new List<Data>();
list.Add(new Data(12345, "56789"));
Alex
  • 8,908
  • 28
  • 103
  • 157
James
  • 80,725
  • 18
  • 167
  • 237
  • @weston I would be interested in hearing your justification on that because according to the [docs](http://msdn.microsoft.com/en-us/library/ah19swz4(v=vs.71).aspx) it seems more than acceptable - `The struct type is suitable for representing lightweight objects such as Point, Rectangle, and Color. Although it is possible to represent a point as a class, a struct is more efficient in some scenarios. For example, if you declare an array of 1000 Point objects, you will allocate additional memory for referencing each object. In this case, the struct is less expensive.` – James Oct 07 '13 at 18:24
  • 1
    @weston not only that, it's more efficient than a class in the scenario where there is potentially going to be lots of them e.g. a `List`/`T[]`. So in my opinion, this is a *better* suggestion than a class. – James Oct 07 '13 at 18:26
  • 1
    +0: custom object is good idea, but suggesting to use `struct` without making sure person have good understanding of differences is dangerous. (Also seeing person trying to compile something like `list[0].StringData = "test"` is rare treat). – Alexei Levenkov Oct 07 '13 at 18:29
  • When you pass a struct around, it's passing by value, so if you want to consider efficiency, consider that. That is also the main problem with mutable structs. It is hard to see that they are structs, so if you modify a value, that altered value only has a local lifespan if you like, as per Alexei's example. – weston Oct 07 '13 at 18:32
  • There are times to be concerned about memory sure, but the bugs you can see are a hell of a price to pay for those few bytes saved. – weston Oct 07 '13 at 18:36
  • "local scope", that's what I was looking for, rather than "local lifespan" – weston Oct 07 '13 at 18:45
  • @weston / Alexei so basically your justification is because the OP *may* not understand how to use it? Sorry but that's a cop out in my opinion, the goal of this site is to *learn* and offer solutions that work. In scenarios like this where I have light-weight, non-reference type data I use `struct`'s hence my answer. – James Oct 07 '13 at 18:45
  • No, it's because we have more experience that we choose to avoid the use of structs unless there is a *real* need. We are trying to teach that. Don't need to teach newbies to use structs, newbies tend to use them too much (I'm not calling you a newbie!) – weston Oct 07 '13 at 18:53
  • @weston I have used them on various occasions without any problem, admittedly at lower level. I do get the point you are trying to make with regards to understanding their usage. However, I still don't agree with your statement - given the circumstances I feel this *is* an appropriate usage for them, personally I don't think there is enough context for you to decide whether or not it isn't, it's really just your opinion vs mines at this point :) – James Oct 07 '13 at 19:06
  • It's not just my opinion, you quoted Microsoft earlier, well give this a read: http://msdn.microsoft.com/en-us/library/ms229017.aspx from here: http://stackoverflow.com/questions/85553/when-should-i-use-a-struct-instead-of-a-class also this: http://stackoverflow.com/questions/521298/when-to-use-struct-in-c and note I would not have said anything has your struct been immutable, which is key to avoiding problems. – weston Oct 07 '13 at 19:56
  • @weston I have read that material in the past when I myself wasn't sure about the use of structs. However, it doesn't really clarify your point - in this particular scenario the OP want's to group some value-type data together, a struct seems a perfect scenario for this given the performance advantages over a class. The fact the struct is mutable was an oversight on my part, it was just an example written off the cuff. I have updated to an immutable struct though to avoid any of the common pitfalls, however, if you had clarified this point earlier I would have agreed & updated sooner :) – James Oct 07 '13 at 21:13
  • How to search by first value in this list? – Leo Apr 18 '14 at 15:13
38

With the new ValueTuple from C# 7 (VS 2017 and above), there is a new solution:

List<(int,string)> mylist= new List<(int,string)>();

Which creates a list of ValueTuple type. If you're targeting .NET Framework 4.7+ or .NET/.NET Core, it's native, otherwise you have to get the ValueTuple package from nuget.

It's a struct opposing to Tuple, which is a class. It also has the advantage over the Tuple class that you could create a named tuple, like this:

var mylist = new List<(int myInt, string myString)>();

That way you can access like mylist[0].myInt and mylist[0].myString

Magnetron
  • 7,495
  • 1
  • 25
  • 41
  • This is the way. Field Names for your Tuple Members is nice and makes your code easier to understand. Granted we should have Classes and Structs to define such pairings, but for one-off odds and ends (and rapid prototyping), this does the job well. Note: I've read that if you add the Package and then later upgrade to 4.7, you may run into issues until you uninstall it. – MikeTeeVee Dec 08 '20 at 09:56
21

Since your example uses a generic List, I assume you don't need an index or unique constraint on your data. A List may contain duplicate values. If you want to insure a unique key, consider using a Dictionary<TKey, TValue>().

var list = new List<Tuple<int,string>>();

list.Add(Tuple.Create(1, "Andy"));
list.Add(Tuple.Create(1, "John"));
list.Add(Tuple.Create(3, "Sally"));

foreach (var item in list)
{
    Console.WriteLine(item.Item1.ToString());
    Console.WriteLine(item.Item2);
}
andleer
  • 22,388
  • 8
  • 62
  • 82
6

Use C# Dictionary datastructure it good for you...

Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("one", 1);
dict.Add("two", 2);

You can retrieve data from Ditionary in a simple way..

foreach (KeyValuePair<string, int> pair in dict)
{
    MessageBox.Show(pair.Key.ToString ()+ "  -  "  + pair.Value.ToString () );
}

For more example using C# Dictionary... C# Dictionary

Navi.

Navib
  • 71
  • 1
  • 1
5

Not sure about your specific scenario, but you have three options:

1.) use Dictionary<..,..>
2.) create a wrapper class around your values and then you can use List
3.) use Tuple

walther
  • 13,466
  • 5
  • 41
  • 67
3
List<Tuple<string, DateTime, string>> mylist = new List<Tuple<string, DateTime,string>>();
mylist.Add(new Tuple<string, DateTime, string>(Datei_Info.Dateiname, Datei_Info.Datum, Datei_Info.Größe));
for (int i = 0; i < mylist.Count; i++)
{
     Console.WriteLine(mylist[i]);
}
  • You should at least try to make your answer match the question. The OP doesn't want `` - they want ``. Although the approach is the same, there's no point in confusing the issue. – Simon MᶜKenzie Apr 08 '14 at 06:30
2

For that, you could use a Dictionary where the int is the key.

new Dictionary<int, string>();

If you really want to use a list, it could be a List<Tuple<int,string>>() but, Tuple class is readonly, so you have to recreate the instance to modifie it.

Samuel Poirier
  • 1,240
  • 2
  • 15
  • 30
0

The Usual way of implementing such thing is by using Model Class and creating properties inside Model Class Example:

public class YourClassName
{
 //your properties
 public Type Name { get; set; }
 public Type Name { get; set; }
 //and so on
} 

and the use this class model for creating a list of this model:

public List<YourClassName> ListName { get; set; }