Reputation: 2943
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
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
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