It is because your struct is empty, there is no members.
It seems that the dictionary considers they are the same, like if null
.
And Key of Dictionary must be unique.
I notice that the compiler doesn't throw a non assignment error... that it throws if the struct have members...
For the type of blood you can use an enum like that, no need to create a struct or a class that are for encapsulating data structure, because enum are enumarated integers values (like parameters or lists of states):
public enum BlooType
{
O,
A,
B,
AB
}
Here O = 0, A = 1, B = 2 and AB = 3
Perhaps you need that if I understand, to made the thing simple:
public enum BlooType
{
Op, // = 0
Om,
Bp,
Bm,
Ap,
Am,
ABp,
ABm // = 7
}
And rhesus :
public enum Rhesus
{
Positive,
Negative
}
Here an explanation of what enum are and how to use them:
https://www.tutorialspoint.com/csharp/csharp_enums.htm
Now you can write:
dic.Add(BloodType.ABp, new List<BloodType> { BloodType.Op, BloodType.Om ... });
To get a readable string of a blood type you can write for example:
string strType = Enum.GetName(BlooType.Op);
Or:
string strType = Enum.GetName(dic[typeBlood][0]);
Here an IL explanation of the exception.
With empty struct:
struct A
{
}
static void Main(string[] args)
{
A value1;
A value2;
var list = new List<A>();
list.Add(value1);
list.Add(value2);
}
IL code generated:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 24 (0x18)
.maxstack 2
.entrypoint
.locals init (
[0] valuetype ConsoleApp1.Program/A value1,
[1] valuetype ConsoleApp1.Program/A value2,
[2] class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A> list
)
// (no C# code)
IL_0000: nop
// List<A> list = new List<A>();
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::.ctor()
IL_0006: stloc.2
// list.Add(item);
IL_0007: ldloc.2
IL_0008: ldloc.0
IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::Add(!0)
// (no C# code)
IL_000e: nop
// list.Add(item2);
IL_000f: ldloc.2
IL_0010: ldloc.1
IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::Add(!0)
// (no C# code)
IL_0016: nop
// }
IL_0017: ret
} // end of method Program::Main
With non empty struct and assignment:
struct A
{
public int v;
}
static void Main(string[] args)
{
A value1 = new A();
A value2 = new A();
var list = new List<A>();
list.Add(value1);
list.Add(value2);
}
IL code generated:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 40 (0x28)
.maxstack 2
.entrypoint
.locals init (
[0] valuetype ConsoleApp1.Program/A value1,
[1] valuetype ConsoleApp1.Program/A value2,
[2] class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A> list
)
// (no C# code)
IL_0000: nop
IL_0001: ldloca.s 0
// A item = default(A);
IL_0003: initobj ConsoleApp1.Program/A
// (no C# code)
IL_0009: ldloca.s 1
// A item2 = default(A);
IL_000b: initobj ConsoleApp1.Program/A
// List<A> list = new List<A>();
IL_0011: newobj instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::.ctor()
IL_0016: stloc.2
// list.Add(item);
IL_0017: ldloc.2
IL_0018: ldloc.0
IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::Add(!0)
// (no C# code)
IL_001e: nop
// list.Add(item2);
IL_001f: ldloc.2
IL_0020: ldloc.1
IL_0021: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<valuetype ConsoleApp1.Program/A>::Add(!0)
// (no C# code)
IL_0026: nop
// }
IL_0027: ret
} // end of method Program::Main
When the struct have no members and vars are not assigned, this code is missing:
IL_0001: ldloca.s 0
// A item = default(A);
IL_0003: initobj ConsoleApp1.Program/A
// (no C# code)
IL_0009: ldloca.s 1
// A item2 = default(A);
IL_000b: initobj ConsoleApp1.Program/A
I'm not involved in IL but it seems that when the struct is empty, the compiler does not throw an error and uses the variables of struct type as references (memory contains 0 i.e. null
).