Reputation: 57
in C# I need to keep data in a dictionary object, looks like:
Dictionary<string, Dictionary<string, string>> MyDict =
new Dictionary<string, Dictionary<string, string>>();
Now I realised, that I would need in some cases some other (not dictionary-like) data as value of the main dict.
Is there any kind of Problem or limitation, if I just instance the main dict. as:
Dictionary<string, object> MyDict = new Dictionary<string, object>();
in the object field I could put string, dictionary, whatever..
Thanks in advance, Best regards, Steven
Upvotes: 3
Views: 49271
Reputation: 112782
You can do that. After retrieving data from the main dictionary, you will have to cast the result to an appropriate type:
object obj;
If(mainDict.TryGetValue("key", out obj)) {
var dict = obj as Dictionary<string, string>>;
if (dict != null) {
// work with dict
} else {
var value = obj as MyOtherType;
....
}
}
But note that this is not type-safe; i.e., the compiler can only partially check the validity of your code regarding the values of type object
.
Alternatively you could try a more object-oriented solution
public abstract class MyBaseClass
{
public abstract void DoSomething();
}
public class MyDictClass : MyBaseClass
{
public readonly Dictionary<string, string> Dict = new Dictionary<string, string>();
public override void DoSomething()
{
// So something with Dict
}
}
public class MyTextClass : MyBaseClass
{
public string Text { get; set; }
public override void DoSomething()
{
// So something with Text
}
}
Then declare your main dictionary with
var mainDict = new Dictionary<string, MyBaseClass>();
mainDict.Add("x", new MyDictClass());
mainDict.Add("y", new MyTextClass());
...
MyBaseClass result = mainDict[key];
result.DoSomething(); // Works for dict and text!
Upvotes: 5
Reputation: 161012
Yes, your dictionary would not be strongly typed anymore - in the first approach you could do something like:
string value = myDict["foo"]["bar"];
In the second approach this is not possible anymore since you have to cast first:
string value = ((Dictionary<string,string>)myDict["foo"])["bar"];
It sounds like your problem could be solved with a better design approach. Usually the need to store different kind of objects in the same data structure can be avoided by re-designing the solution - so why do you need to do this?
Edit:
If you just want to handle null
values you could just do something like:
string value = myDict["foo"] != null ? myDict["foo"]["bar"] : null;
Or wrapped in an extension method:
public static T GetValue<T>(this Dictionary<T, Dictionary<T,T>> dict,
T key, T subKey) where T: class
{
T value = dict[key] != null ? dict[key][subKey] : null;
return value;
}
string value = myDict.GetValue("foo", "bar");
Upvotes: 5
Reputation: 81567
By using object as the value in your dictionary you will incur some risk and complications:
You should probably rethink your design. But if you really want a the flexibility you could create a new type that would work as the value type. Something like:
class MySpecialType
{
public Dictionary<string, string> MyStringDictionary { get; set; }
public string MyStringVal {get; set;}
public Type ActiveType { get; set; } // property would specify the current type
// ...
Your main dictionary declaration would then look something like:
Dictionary<string, MySpecialType> MyDict = new Dictionary<string, MySpecialType>();
You could use the ActiveType property or create an enum which would specify the type. You could also have static util functions in the class which could help with returning the right instance and type...
Upvotes: 3
Reputation: 31651
You will pay a performance penalty when you unbox the System.Object
, but other than that there isn't a problem with your approach other than excessive casting for indexers (due to weak typing).
You may consider using a System.Tuple if you are using .NET 4.
Upvotes: 0
Reputation: 38179
You'll loose strong types and all their benefits.
Can you not create a new class that has a Dictionary property and add your other data to it:
public class CallItWhatYouLike
{
public Dictionary<string, string> Dictionary {get; set;}
public int AnotherProperty {get; set;}
...
}
var MyDict = new Dictionary<string, CallItWhatYouLike>();
Upvotes: 1
Reputation: 25569
Well, your code will be less typesafe and you will need runtime type checks and type casts, but otherwise you can use object
as a dictionary value type and store any types there.
Upvotes: 0
Reputation: 64943
No, there's no problem. If you need to type the value as Dictionary<string, string>
just cast it and you'll have this solved.
Upvotes: 0