tags:

views:

80

answers:

3

Hi, I declared a static mainDict like this,

private static Dictionary<string, object> mainDict = new Dictionary<string, object>();
Dictionary<string, object> aSubDict = new Dictionary<string,object>();
mainDict.Add("StringA0Key", "StringValue");
mainDict.Add("StringA1Key", aSubDict);

How to detect the Value Type is a string(StringValue) or dictionary(aSubDict)

I need to detect the value type and loop into "aSubDict", otherwise i just print the "StringValue". thank you.

[updated]

Thanks for your help, i closed my question with the updatd code below.

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

class Program
{
    private static Dictionary<string, object> mainDict = new Dictionary<string, object>();

    public static void Main()
    {


        Dictionary<string, object> aSubDict = new Dictionary<string, object>();
        mainDict.Add("sA0Key", "sA0Value");
        mainDict.Add("sA1Key", aSubDict);         
        aSubDict.Add("sSubKey","sSubValue");

        foreach (string theKey in mainDict.Keys)
        {
            if (!ReferenceEquals(null, mainDict[theKey]) && (mainDict[theKey] is Dictionary<string, object>))
            {
                //Console.WriteLine("type of aSubDict");
                foreach (string subKey in aSubDict.Keys)
                {
                    if (!ReferenceEquals(null,aSubDict[subKey]) && aSubDict[subKey] is Dictionary<string, object>)
                    {    
                        Console.WriteLine("type of Child Dict");
                    }
                    else if (!ReferenceEquals(null, aSubDict[subKey]) && (aSubDict[subKey] is string))
                    {
                        Console.WriteLine("subKey = {0}, subValue = {1}", subKey, aSubDict[subKey]);
                    }
                }

            }
            else if (!ReferenceEquals(null, mainDict[theKey]) &&  (mainDict[theKey] is string))
            {
                // Console.WriteLine("type string");
                Console.WriteLine("Key = {0}, Value = {1}", theKey, mainDict[theKey]);
            }
        } 
    }
}
+4  A: 
if (obj is IDictionary)

This is because all Dictionaries, even if generic, implement the IDictionary interface.

Also watch out for NullReferenceException.

if (!ReferenceEquals(null, obj) && obj is IDictionary)

update

You test for is IDictionary<string, object>. Possibly the sub-dictionary is different by Type Parameters like IDictionary<int,string> or any number of combinations of key/value Types - this means it's a different Type to the compiler. However if you want to treat it as a loosley-typed dictionary then just test for is IDictionary and use the IDictionary members - note those members take object references.

Dictionary<string, int> is not the same type as Dictionary<int, object> (They can never be the same type). However both are of the implemented type IDictionary - this is why IDictionary might be what you're searching for in this scenario.

I've taken the middle section of your code upate and modified it for IDictionary, although I haven't tested the logic or tried compiling it...

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

...

if (!ReferenceEquals(null, kvp) && (kvp is IDictionary))
        {

            foreach (DictionaryEntry entry in aSubDict)
            {
                if (entry.Value is IDictionary)
                {
                    Console.WriteLine("iDictionary found");
                }
                else
                {
                    Console.WriteLine("SubKey = {0}, SubValue = {1}", entry.Key, entry.Value);
                }
            }

Likely you'll need to modify the logic because the sub-dictionary is either in the .Key or or .Value of the 'parent' dictionary entry, but this is a start.

John K
Paulo Santos
@jdk and Paulo, I updated my post, i still can't understand all your suggestion. Would you please give more details about my code above. Thanks.
Nano HE
I provided a speculative update. Is that going in the right direction for your requirements?
John K
John K
Please also see Gabriel's answer (below) to keep in mind that if you want to use "is IDictionary" instead of "is IDictionary<string, object>" you will need to be sure your project contains a reference to System.Collections.
BillW
@Billw, Sure,I would remember it in mind. btw, i noticed that the LOOP expression changed from "foreach (KeyValuePair<string, object> pair1 in mainDict)" to "foreach (string theKey in mainDict.Keys)" @jdk. Thank you.
Nano HE
+2  A: 

Check that it implements the interface System.Collections.IDictionary

if (mainDict["StringA1Key"] is IDictionary)
{
}
Gabriel McAdams
Hi, Could i detect "if (mainDict[1].Value is IDictionary)" ?
Nano HE
@Nano: Check my modified answer. This is how to check the type
Gabriel McAdams
@Bill: 1. I fixed the index thing. I was not thinking. 2. IDictionary is not the one from the Generics namespace, it is the one from the System.Collections namespace. I modified my answer to reflect this as well.
Gabriel McAdams
@Gabriel Negative vote on your answer deleted. Comment removed. Thanks for correcting. "All's well that ends well." Shakespeare.
BillW
+1  A: 

If your goal is to detect if the Value of a given dictionary KevValue pair in mainDict is of the exact Type of aSubDict : i.e. : a Dictionary whose keys are Type string, and values are Type object :

    Type testType = aSubDict.GetType();

    foreach (string theKey in mainDict.Keys)
    {
        if ((mainDict[theKey]).GetType() == testType)
        {
            Console.WriteLine("Match found");
        }
    }

If your goal is to detect if the Value of a given dictionary KevValue pair in mainDict is the instance aSubDict :

    foreach (string theKey in mainDict.Keys)
    {
        if (mainDict[theKey] == aSubDict)
        {
            Console.WriteLine("Match found");
        }
    }

Let's round this out with a complete example that filters on 'Type only and does not use GetType() :

    foreach (string theKey in mainDict.Keys)
    {
        if(mainDict[theKey] is Dictionary<string, object>)
        {
            Console.WriteLine("type of aSubDict");

        } else if (mainDict[theKey] is string)
        {
            Console.WriteLine("type string");
        }
    }

All code above tested in Visual Studio Beta 2010 beta 2 compiled against FrameWork 3.5 (not the "client mode" 3.5, the full monte).

BillW
Great. This is what i want. Thank you.
Nano HE