Re: Which generic?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



wsmckenz wrote:
On Jul 1, 3:50 pm, Jeroen Mostert <jmost...@xxxxxxxxx> wrote:
wsmckenz wrote:
I want a collection of things, Columns in this case, which are indexed
by name (which would imply a Dictionary<string, Column>) but are also
in a guaranteed order (which would imply List<Column>). I want to be
able to write:
m_columns[i];
// or
m_columns["FRED"];
and have both work.
i also want
foreach(Column col in m_columns)
{
}
To enumerate in the order that the columns were appended to the list.
Is there a generic that serves the purpose or do I have to write my
own?
Either SortedList<> or SortedDictionary<> should do.


I dont think that works. For instance, the following code
using System;
using System.Collections.Generic;

public struct Column
{
public string name;
public string description;
public int type;
public Column(string nameIn, string descIn, int typeIn)
{
name = nameIn;
description = descIn;
type = typeIn;
}
}

public class foo
{
static Column[] myCols =
{
new Column("ABC", "abc", 2),
new Column("DEF", "def", 3),
new Column("XYZ", "xyz", 1),
new Column("QRS", "qrs", 2)
};

static void Main()
{
SortedList<string, Column> cols = new SortedList<string,
Column>();
foreach(Column col in myCols)
{
cols.Add(col.name, col);
}

foreach(string name in cols.Keys)
{
System.Console.Out.WriteLine(cols[name].name);
}

System.Console.Out.WriteLine("====================");

for (int i=0; i<cols.Count; ++i)
{
System.Console.Out.WriteLine(cols.Values[i].name);
}
}
}


Produces the following output:

C:\work>generic
ABC
DEF
QRS
XYZ
====================
ABC
DEF
QRS
XYZ

This is not what I want. I want the items to remain in the list in
the order i put them there, but also be accessible by name.

Ah, I see. In that case, you indeed have to roll your own. This shouldn't be hard: you want to aggregate a List<Column> and a Dictionary<string, Column>. The class basically implements IList<Column> and IDictionary<string, Column> and delegates as appropriate:

class ColumnCollection : IList<Column>, IDictionary<string, Column> {
private readonly IList<Column> columnsByIndex = new List<Column>();
private readonly IDictionary<string, Column> columnsByName = new Dictionary<string, Column>();

#region IList<Column> Members

public int IndexOf(Column item) {
return columnsByIndex.IndexOf(item);
}

public void Insert(int index, Column item) {
columnsByIndex.Insert(index, item);
columnsByName.Add(item.name, item);
}

...

and so on. Aside from being a fair bit of typing, there's little difficulty involved. You'll have to decide at a few points whether you want a list-centric view or a dictionary-centric view of your class (such as when you're enumerating).

--
J.
.



Relevant Pages

  • Re: RasEnumEntries returns only 1 dial up entry (PocketPC)
    ... public int reserved1 = 0; ... public string szPhoneNumber; ... public extern static uint RasHangUp( ... // buffer to hold error string ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: how to declare GetOpenFileNameEx in C#
    ... public IntPtr hwndOwner; ... public string lpstrCustomFilter; ... public int nMaxCustFilter; ... public IntPtr lpstrFile; ...
    (microsoft.public.dotnet.framework.compactframework)
  • RE: WNetAddConnection2
    ... I managed to recreate my error from the command prompt with the following ... So I got to thinking about the username and tried ... ... public int dwScope; ... public string lpRemoteName; ...
    (microsoft.public.dotnet.framework.interop)
  • Namespace confusion
    ... fulfilmentRequestID = dataAccessObject.GenerateFulfilmentRequest(orderID, ... public string status; ... public int customerID; ...
    (microsoft.public.dotnet.framework.aspnet.webservices)
  • Re: How do I use WinHttpGetProxyForUrl from WinHttp.dll
    ... WINHTTP_AUTO_DETECT_TYPE_DNS_A in autodetect flags. ... > public struct WINHTTP_AUTOPROXY_OPTIONS ... > public int dwAutoDetectFlags; ... > public string lpszAutoConfigUrl; ...
    (microsoft.public.dotnet.framework.interop)