0

I've seen this in a question: :

edit: type's are known before adding to dictionary

You could use Dictionary<string, object>, then you'd need to cast the results:

int no = 1;       
string str = "world";
Dictionary dict = new Dictionary<string,object>();

dict.add( "intObj" , no  );
dict.add( "intObj" , str );


int a = (int) Storage.Get("age"); //everthing was perfect till i see cast .
string b = (string) Storage.Get("name");
double c = (double) Storage.Get("bmi");

question: how can i modify square-Brackets [] to cast type before returnig value so it will look like this;

int a = dict["intObject"] ;   //we got rid of casting forever
string b = dict["stringObject"] ;

thank you.

Community
  • 1
  • 1
bh_earth0
  • 2,537
  • 22
  • 24
  • 1
    You can't. You don't have the ability to modify `Dictionary`'s indexer logic. Not that it would make sense to do anyway. You will need to cast. – Yuval Itzchakov Oct 29 '15 at 11:50
  • Short answer : Its not possible. Long answer : Because this requires run time operations such as type checks and unboxing. so you cant do this in compile time. One way is to divide your dictionary into chunks that each one gives a known value. except using object. you can do this with linq so for example one dictionary gives `int` another gives `string` etc... – M.kazem Akhgary Oct 29 '15 at 12:00

2 Answers2

2

You can't directly modify the indexer. What you can do is create an extension method that does this (partially) for you:

public static class DictionaryExtensions
{
    public static T Get<T>(this Dictionary<string, object> dictionary, string key)
    {
        object value = null;
        return dictionary.TryGetValue(key, out value) ? (T)value : default(T);
    }
}

Note this has a few shortenings:

  1. If someone inserts a key with a null, you'll get a cast exception at runtime if the value is a value type.

  2. If the value doesn't exist for value types, you'll get the default for each primitive. Note this way you can't really indicate if the key was or was not present in the dictionary.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • haha. OP confused to accept which answer, i just saw it went to you then jon skeet then you again xD or probably was misclick – M.kazem Akhgary Oct 29 '15 at 12:05
  • 2
    its not 100% what i want. but nothing is perfect in this world – bh_earth0 Oct 29 '15 at 12:08
  • yes i did changed. xD . there is no answer for the question. this is usable. but in logic i have to choose jon skeets. – bh_earth0 Oct 29 '15 at 12:11
  • @blackholeearth0 if you know the key and the type of value like you typed `int a = dict["intObject"] ;` then this is the answer. if you dont know about keys and values then you should go jon skeets answer so for example you write dynamic `a = dict["something"] ;`. – M.kazem Akhgary Oct 29 '15 at 12:14
  • yes the types are previosly defined. let me add the question – bh_earth0 Oct 29 '15 at 12:15
  • sorry sorry i dont want this . when i call it i have to dict["key"].get actually this is longer . i dont want to specifiy the T as the types are already definedwhen adding to dictionary ex: dict.add("key", intval1 ). so im deaccepting – bh_earth0 Oct 29 '15 at 12:41
1

(Answered before the .NET 2.0 requirement was mentioned - it may still be useful for others.)

You can use a Dictionary<string, dynamic> instead - at which point the compile-time type of the expression dict["stringObject"] will be dynamic. The assignment to a variable of type string will then perform the conversion at execution time.

You can't change how Dictionary<string, object> behaves though. You would have to change the type argument... and no, you can't do this with .NET 2.0.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194