FutureCake
FutureCake

Reputation: 2943

add duck-typed struct to dictionary c#

I want to add a duck-typed struct to an dictionary but i get the following error:

Argument 2: cannot convert from '[] options>' to 'UnityEngine.Object'

This is the code i have:

public class Dynamic_Interface
{
    private static Dictionary<int, Object> Interface_steps = new Dictionary<int, Object>();

    Dynamic_Interface()
    {
        var sentences = new[] 
        {
            new
            {
                identifier = 1,
                text = "string explain",
                options = new[] 
                {
                    new
                    {
                        next = 2,
                        value = "this is the first option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the second option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the third option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the fourth option"
                    },
                }
            },
            new
            {
                identifier = 2,
                text = "string explain second var",
                options = new[] 
                {
                    new
                    {
                        next = 3,
                        value = "this is the second first option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second second option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second third option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second fourth option"
                    }
                }
            },
        };

        foreach (var sentence_obj in sentences)
        {
            Interface_steps.Add(sentence_obj.identifier, sentence_obj);
        }
    }
}

So in the end i want a dictionary containing each object in the sentences[] that has the the identifier key as name in the dictionary.

I am used to to javascript and this is really my first time doing c# so sorry for the beginner mistake. But i really cant seem to find how to get this to work.
If something is unclear let me know so i can clarify..

Upvotes: 2

Views: 154

Answers (2)

Freggar
Freggar

Reputation: 1056

So, what is happening here?
When we take a closer look at the error message

Argument 2: cannot convert from '[] options>' to 'UnityEngine.Object'

it tells us that we are trying to convert the options array to the type UnityEngine.Object. Hmmm. this is weird we didn't define our Dictionary with this Unity nonsense, so why is it using that instead of C#'s Object class?!

Well you are propably using other Unity classes an probably have something like

using UnityEngine;

in your namespace. The problem with C# is that it's Object class also resides in a namespace which is called System, making it only fully identifieable by using System.Object. So if you don't have

using System;

it will happily try to use UnityEngine.Object instead of System.Object when you type Object. Thus this weird compiler error will occur.


So just use System.Object and everything is fine right?
Well Yes. But there is more to the Story!

C# also has defined aliases for it's most common types - the so called built-in types:

bool        System.Boolean
byte        System.Byte
sbyte       System.SByte
char        System.Char
decimal     System.Decimal
double      System.Double
float       System.Single
int         System.Int32
uint        System.UInt32
long        System.Int64
ulong       System.UInt64
object      System.Object
short       System.Int16
ushort      System.UInt16
string      System.String

You will find that lowercase object is just an alias to System.Object. But wait! Doesn't that make object always use System.Object regardless of our using statements? The answer is yes, yes it does...

Let me illustrate by following example how tricky namespacing in C# can actually be:

public class Object
{
    public string Name { get; set; }
}
public class TestConsole
{
    public static void Main(string[] args)
    {
        Object fakeObject = new Object(); // -> Custom Object class
        object realDeal = new object();   // -> System.Object

        string name = fakeObject.Name    // OK
        name = realDeal.Name             // NOT OK
    }
}

So does that mean that we should always use the built-in alias when using System classes? Not really but we should rather use the naming convention that is used by Microsoft. That means whenever you use the class like a datatype you should use the built-in and whenever you use static members of the class you should use it's full name. For example:

object humberto = "humberto";
string rudolf = "rudolf";
Object.Equals(humberto, rudolf);

Upvotes: 2

zambari
zambari

Reputation: 5035

Strong typing is one of advantages of C#, its a bit more verbose than ducktyping but saves you a lot of headache, if possible try to restrain from var, its a few characters shorter but if you use strong types its much harder to accidentally ask the compiler to do something different than what you actually want:

Two options for alternative approaches that seem to immediately stand out are

class myClass { int next; string value; };
Dictionary <int, myClass> dict;

or, possibly, although I think this is not quite what you are trying to do

Dictionary<int, Dictionary<int,string>> dict; 

Second option doesn't require you to declare a class type, but remember that dictionaries require unique keys. It kind of reads that you want to use array index as a key, but then you still use a dictionary, is there a reason for that? My solutions might be a bit off, but I'd be happy to suggest more if you could explain what kind of lookup you want to make.

Maybe you want to combine the above into

Dictionary<int, Dictionary<int,myClass>> dict; 

Upvotes: 0

Related Questions