How to call value by key when key is an object?

I’ve been playing with dictionaries, array, hashtables, etc. but I can’t find just what I’m looking for.

basically I want to have a key that is from class Item, ex: Item.StonePick
and a value assigned to it for how many that player has in the inv, ex: 3

now StonePick is an item so it has a _name and lots of variables that would be great to access so I can display “Stone Pick” not StonePick etc. when I got through the list and print out the player inventory, or quests, or achievments or whatever.

I have it semi-working via linq with a hashtable _playerQuests:

public void Act(){
		if(Player._playerQuests.ContainsKey(Quests.Cliff01)) {
			int place;
			for (int i = 0; i < Player._playerQuests.Count; i++){
				if (Player._playerQuests.Keys.ElementAt(i) == Quests.Cliff01){ place = i; }
			}
			if (Player._playerQuests.Values.ElementAt(place) == 1){ _chat = "1"; }
		}
		else { _chat = "0"; }
	}

but that means it has to go through everything all the time just so I can call from the index number to access the Item._name etc.

There must be a better way??

What I really just want is:
Dictionary playerInventory;
and
Dictionary playerQuests;
etc.

Can anyone offer some suggestions?
Should I just setup predefined Arrays of 200 until my hard coded Quests go over 200 then change that array to 300 and keep a log of what quest is where? then I could hard call everything directly, but that would destroy any sort of loose search functionality…?

You can make your Item object implement System.IEquatable and override the method GetHashCode(). That way your Item can be used as a Key based on the ID or Name that you set to it.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class Item : System.IEquatable<Item> {

	public Item(string name) {
		Name = name;
	}

	public string Name {
		get;
		set;
	}

	public bool Equals(Item other) {
		return Name == other.Name;
	}

	public override int GetHashCode(){
		return Name.GetHashCode();
	}
}

public class ObjectKey : MonoBehaviour {

	IDictionary<Item, uint> items = new Dictionary<Item, uint>();

	// Use this for initialization
	void Start () {
		Item item1 = new Item("Item1");
		Item item2 = new Item("Item2");

		items[item1] = 2;
		items[item2] = 45;

		foreach (Item item in items.Keys) {
			Debug.Log(item.Name + " -> Qty: " + items[item] + " " + item);
		}

		Item dummySearchItem = new Item("Item1");

		Debug.Log("Search Qty: " + dummySearchItem.Name + " -> Qty: " + items[dummySearchItem]);

	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

Other option is to create a wrapper object that keeps a reference to the item and the quantity of that item, and store that on a dictionary using the item ID or Name as the key.

public class InventoryItem {

	Item item;
	uint qty;

}