Passing a "reference" to Dictionary element? - c#

So I have:
ConcurrentDictionary<string, int> dict;
I want to pass a reference to one of its elements, suppose dict["x"] to a method, and allow that method to change/set that element. Is it possible to do exactly that, or do I have to pass the dictionary itself? Also, is it possible to do so even if the element does not exist as a key in the dictionary? Or does it already has to be a valid key contained in the dictionary?

Yes, by using a delegate. This delegate can be called from within the changing function. The delegate will then change or set the key/value inside the dictionary.
void DoChangeMyElement<T>(Action<T> changeIt)
{
changeIt(123);
}
You can call this method with:
ConcurrentDictionary<string, int> dict = new ...;
DoChangeMyElement(value => dict["X"] = value);

I want to pass a reference to one of its elements, suppose dict["x"] to a method, and allow that method to change/set that element. Is it possible to do exactly that, or I have to pass the dictionary itself ?
Just pass the dictionary, as Sam I am said it is a reference type anyway.
Also, is it possible to do so even if the element does not exist as a key in the dictionary ?
No that's not possible, you'd have to add to it, then send it to the function.

You'd have to pass the whole dictionary and key, and let the method do what it needs to. The basic reason for this is that you can only pass fields and local variables by reference, not properties (including indexer properties).
If you were really desperate to do so, you could use reflection and/or delegates to get what you want done, but it's not the best way to do it.

There's no harm in passing the whole Dictionary. It itself is a reference type after all, and passing the Dictionary would be better form than passing by reference.
but I suppose you could encapsulate you int and pass it like that
public class IntContainer
{
int value;
}

Related

Accessing a generic dictionary via casting at runtime

Our program has a dictionary of type:
Dictionary<TKey, TCache>();
where TKey and TCache are whatever generic types the encompassing method is given, and TCache is a CacheBase.
In another method I need to reference this object (which is stored in another dictionary where it's stored as an object) and remove a key/value pair from it. At runtime I have the TKey object boxed as an 'object' class.
How would I go about this? I can't cast to Dictionary because this method is not generic and won't know at compile time what type of cache/key it is. These are passed as parameters.
Is there a way to use reflection to cast the dictionary from Dictionary to effectively
Dictionary<CacheBase<key.GetType()>, key.GetType()>
I know this can easily fixed by not using the methods generics and instead making the Dictionary a Dictionary and making CaseBase extend an empty CacheBase, but my supervisor insisted I do it this way
Managed to fix it on my own, but for future people,
Essentially, I had to flip the perspective. I can't cast an existing dictionary to another equivalent type via reflection, however the goal was to do so so I could modify the dictionary with Types at runtime.
So instead, I made a generic method that would communicate with the dictionary in the way it wanted (if it expects a TKey, I made my method take a TKey so it would work properly).
e.g.
public void RemoveFromCache<TCache, TKey>( Type type, TKeykey ) where TCache : CacheBase<TKey> {
((Dictionary<TKey, TCache>)m_caches[type]).Remove( key );
}
After that, I simply used reflection to call my generic method at runtime with the types passed in as the appropriate generics
e.g.
var keyType = key.GetType();
var removeFromCache = GetType().GetMethod( nameof( RemoveFromCache ) ).MakeGenericMethod( type, keyType );
removeFromCache.Invoke( this, new object[] { type, key } );
And that let me communicate with a Dictionary that was boxed into an object at runtime with only types available.

iterate .net dictionary as object

I have an interesting problem. I need to write a general (I'd use the word "generic" but that would conflict with what I'm after) routine that I can hand an instance of a dictionary object instance and iterate over the content of said object as a dictionary and return the content as literal values. The difficulty lies in that the method parameter will be of type "object", not dictionary.
What I need now and can't figure out how to do, is a way of iterating over a Dictionary<K, V> of arbitrary keys and values. Easy to do if you know the types going in, but as I say, the origin of the dictionary will be as an object where object.GetType().GetInterfaces() has typeof(IDictionary) in the results. I won't know (and shouldn't need to know) the dictionary key type or the value type.
My current need is to process something that is Dictionary<string, SomeClass>;. Once I get the list of keys I can use a foreach on each instance, figure out that it's a string and proceed from there. With the Values it'll be an instance of some class (the class will change but again, I can pass that off to another set of methods to extract the class, extract the properties of the class and extract those values).
The main point of the request is to obtain a method (or two or however many) that will allow me to iterate over a dictionary of unknown types and extract the keys and values, all without knowing the types at compile time. The above Dictionary; is just an example, I need to be able to pass any dictionary. At the moment, I'm not worried about edge cases like Dictionary<Tuple<int, string, SomeOtherClass>, SomeClass>> or things like that, if I can start with Dictionary<string, SomeClass>;, I can probably proceed from there.
It's getting the keys and values out in a form that I can process that I haven't figured out how to do yet.
You mentioned that you have access to the IDictionary<K,V> interface on the object. You can then use get_Keys and get_Values to access the keys and values respectively.
Also, IDictionary<K,V> derives from IEnumerable<KeyValuePair<K,V>> so you can also access the list of key-value pairs using a for-loop similar to lists.
EDIT - Clarification:
IDictionary inputAsDictionary = input as IDictionary;
if (inputAsDictionary != null)
{
// Valid : input is a dictionary.
ICollection dictKeys = inputAsDictionary.Keys; // This is a list of all keys
ICollection dictValues = inputAsDictionary.Values; // This is a list of all values
// Iterate over all keys
for(var dictKey in dictKeys)
{
Console.WriteLine(dictKey); // Print the key
Type dictKeyType = dictKey.GetType(); // Get the type of key if required
// ...
}
// Similarly, iterate over all values
for(var dictValue in dictValues)
{
Console.WriteLine(dictValue); // Print the value
Type dictValueType = dictValue.GetType(); // Get the type of value if required
// ...
}
}
You can also do this using the generic Dictionary<K,V> interface, but it gets a lot more complicated to get the types. You will need to call Type.GenericTypeArguments and go from there. The example I have shown seems simpler.

c# dictionary method as a value

I have a class with a bunch of methods in it, the methods transfer variables elsewhere in my program when called. I want to use a dictionary as the middle man between the methods that transfer data and the methods that call them.
So here is my question. Say I make a dictionary, where the key is an int and I want the value to be the name of a method. I will assign a new value / method each time I add to the dictionary. Is there a value type I can put there that will let me do this?
Dictionary<int, ?> methodKey= new Dictionary<int, ?>();
I tried to find a list of types that dictionary will take but I couldn't find anything specific.
Thanks in advance
Use any delegate type as a type of value. For example:
Dictionary<int, Action>
So, you'll be able to write such things:
dictionary[0] = () => Console.WriteLine("0");
dictionary[1] = Foo;
dictionary[2] = a.Bar;
Specific delegate type depends on your needs - may be, you want for methods to have some input parameters or output/return values, but it should be most common type.
Will all the methods have the same signature? If so you can probably use one of the existing Action or Func delegate, (or you can create a delegate type with that signature), and use that as your second type parameter.
If not, you can use Delegate (or even object) and cast to the appropriate type when you invoke the delegates.

Is there a benefit to using the c# out/ref keyword to "return" > 1 item in a method, instead of an object

Returning multiple things from a method, involves either:
returning an object with properties OR
using the out keyword to simply modify incoming parameters
Is there a benefit to using one system or the other? I have been using objects, but just discovered the out keyword, so wondering if I should bother refactoring.
You shouldn't bother refactoring just to utilize out parameters. Returning a class or struct would be preferred as long as structure is reusable.
A common use for out parameters which I would suggest using is to return a status for a call with that is possible to fail. An example being int.TryParse.
It has the possibility of failing, so returning a bool makes it easy to determing whether or not you should use the out parameter.
Another possible solution to returning multiple values from a method would be to use a Tuple. They can return n number of results. E.g.
public Tuple<bool, bool, string> MyMethod()
{
return new Tuple<bool, bool, string>(false, true, "yep");
}
In general, if the object that you are returning is not used anywhere else outside of the return value of your method or a group of similar methods, it is a good indication that you should refactor. When you need to create a special class simply to be used as a return value of a method, it means that you are working around C#'s inability to return multiple values from a method, so the out keyword may be a very good option for you.
On the other hand, if you use the multi-part return value in other places, such as storing them in collections or passing as arguments to other methods, there's probably no need to refactor, because the return object is meaningful.
Compare these two methods:
interface DictionaryReturn<T> {
T Value {get;}
bool Success {get;}
}
...
class Dictionary<K,V> {
...
public DictionaryReturn<V> TryGetValue(K key) {
...
}
}
or
class Dictionary<K,V> {
...
public bool TryGetValue(K key, out V res) {
...
}
}
The first case introduces a special DictionaryReturn<T> class that provides the value and an indicator that the value was found in the dictionary. There is rarely, if ever, a reason to store or use DictionaryReturn<T> objects outside the call to TryGetValue, so the second option is better. Not surprisingly, it is the second option that the designers of the .NET collections library have implemented.
I prefer to use Object with properties. If you use out keyword, you need to define it in other line. It is not as clear as return Object;
The reason to use out keyword is to ensure that code inside the method always sets a value to the out parameter. It's a compile time check that what you intended to do in the function, you did do.

Can't add keyValuePair directly to Dictionary

I wanted to add a KeyValuePair<T,U> to a Dictionary<T, U> and I couldn't. I have to pass the key and the value separately, which must mean the Add method has to create a new KeyValuePair object to insert, which can't be very efficient. I can't believe there isn't an Add(KeyValuePair<T, U>) overload on the Add method. Can anyone suggest a possible reason for this apparent oversight?
You can use the IDictionary<TKey,TValue> interface which provides the Add(KeyValuePair<TKey,TValue>) method:
IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));
Backup a minute...before going down the road of the oversight, you should establish whether creating a new KeyValuePair is really so inefficient.
First off, the Dictionary class is not internally implemented as a set of key/value pairs, but as a bunch of arrays. That aside, let's assume it was just a set of KeyValuePairs and look at efficiency.
The first thing to notice is that KeyValuePair is a structure. The real implication of that is that it has to be copied from the stack to the heap in order to be passed as a method parameter. When the KeyValuePair is added to the dictionary, it would have to be copied a second time to ensure value type semantics.
In order to pass the Key and Value as parameters, each parameter may be either a value type or a reference type. If they are value types, the performance will be very similar to the KeyValuePair route. If they are reference types, this can actually be a faster implementation since only the address needs to be passed around and very little copying has to be done. In both the best case and worst case, this option is marginally better than the KeyValuePair option due to the increased overhead of the KeyValuePair struct itself.
There is such a method – ICollection<KeyValuePair<K, T>>.Add but as it is explicitly implemented you need to cast your dictionary object to that interface to access it.
((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);
See
List of Explicit Interface Implementations on Dictionary<K, T>'s documentation page (you'll need to scroll down).
Explicit member implementation
The page on this method includes an example.
Should somebody really want to do this, here is an Extension
public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
{
dic.Add(KVP.Key, KVP.Value);
}
but i would recommend to not do this if there is no real need to do this
Unless I'm mistaken, .NET 4.5 and 4.6 adds the ability to add a KeyValuePair to a Dictionary. (If I'm wrong, just notify me and I'll delete this answer.)
https://msdn.microsoft.com/en-us/library/cc673027%28v=vs.110%29.aspx
From the above link, the relevant piece of information is this code example:
public static void Main()
{
// Create a new dictionary of strings, with string keys, and
// access it through the generic ICollection interface. The
// generic ICollection interface views the dictionary as a
// collection of KeyValuePair objects with the same type
// arguments as the dictionary.
//
ICollection<KeyValuePair<String, String>> openWith =
new Dictionary<String, String>();
// Add some elements to the dictionary. When elements are
// added through the ICollection<T> interface, the keys
// and values must be wrapped in KeyValuePair objects.
//
openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));
...
}
As can be seen, a new object of type Dictionary is created and called openWith. Then a new KVP object is created and added to openWith using the .Add method.
just because the enumerator for the Dictionary class returns a KeyValuePair, does not mean that is how it is implemented internally.
use IDictionary if you really need to pass KVP's because you've already got them in that format. otherwise use assignment or just use the Add method.
What would be wrong with just adding it into your project as an extension?
namespace System.Collection.Generic
{
public static class DictionaryExtensions
{
public static void AddKeyValuePair<K,V>(this IDictionary<K, V> me, KeyValuePair<K, V> other)
{
me.Add(other.Key, other.Value);
}
}
}
I'm not 100% sure, but I think the internal implementation of a Dictionary is a Hash-table, which means key's are converted to hashes to perform quick look ups.
Have a read here if you want to know more about hashtables
http://en.wikipedia.org/wiki/Hash_table

Categories