简体   繁体   中英

KeyedCollection GetKeyForItem and Dictionary not working

Here is my issue: It doesn't seem like I can use the .Dictionary property or the GetKeyForItem method. Is there a using statement that I'm missing or something? Essentially, I'd like to retrieve a list of keys for each object in my keyedcollection. I've found another way to do it (shown in the code), but I'm just wondering why the built in .Dictionary and .GetKeyForItem aren't working. I'm thinking that if I can't access these, maybe I set something up incorrectly? Thanks for the help.

namespace testList
{
    public class MyData //data itself has to contain the key. 
    {
        public int Id;
        public List<string> Data;
    }

    public class MyKeyedCollection : KeyedCollection<int, MyData>
    {

//was initially protected. Changed to public. Still can't access this?
        public override int GetKeyForItem(MyData item) 
        {
            return item.Id;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyData nd = new MyData();
            MyData md = new MyData();

            nd.Id = 2;
            nd.Data = new List<string>();
            nd.Data.Add("Random Item");

            md.Id =1;
            md.Data = new List<string>();
            md.Data.Add("First Item");
            md.Data.Add("Second item");

            KeyedCollection<int, MyData> keyd = new MyKeyedCollection();
            keyd.Add(nd);
            keyd.Add(md);
            // doesn't recognize keyd.GetKeyForItem

//Since the mentioned methods aren't working, my only other solution is this:
/*
            int[] keys = new int[keyd.Count];
            for(int i=0; i<keyd.Count; i++)
            {
                keys[i] = keyd[i].Id;
            }
*/
        }
    }
}

Sources:

http://geekswithblogs.net/NewThingsILearned/archive/2010/01/07/using-keyedcollectionlttkey-titemgt.aspx

https://msdn.microsoft.com/en-us/library/ms132438.aspx

The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances.

See documentation for protected keyword.

Since the Class Program is not derived from KeyedCollection it cannot access the method GetKeyForItem

Such collections are normally intended to accomplish fast access time of your items by knowing the key: it is a bit odd to retrieve the key associated to a given item as it may open up to ambiguous scenarios. Indeed, the fact that the method you are trying to override has a protected modifier underlines that it is not supposed to be accessed from the "outside".

As an example: you could store the same object twice but with a different key and your method would not know which key to pick up.

This to say that, depending on your need, the solution you are looking for may be different.

Anyway, to answer your question: the static type of your collection is KeyedCollection, therefore you do not have visibility of the GetKeyForItem method at compile time, since it is protected. Furthermore, it is not allowed to override the access modifier of a method in C# as explained here .

A solution could be to implement the method and expose its result through an additional new method you need to create and that will have access to GetKeyForItem, such as:

protected override int GetKeyForItem(MyData item) {
    return item.Id;
}

public int MyGetKeyForItem(MyData item) {
    return GetKeyForItem(item);
}

Your collection will then need to be initialised as follows to be able to access the MyGetKeyForItem method:

MyKeyedCollection keyd = new MyKeyedCollection();

Then, if you need to retrieve all keys defined in your collection you can first get it as IDictionary first and then retrieve all keys:

int keys = keyd.Dictionary.Keys;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM