Why does int[] is uint[] == true in C#
C# and the CLR have somewhat different conversion rules.
You can't directly cast between int[]
and uint[]
in C# because the language doesn't believe any conversion is available. However, if you go via object
the result is up to the CLI. From the CLI spec section 8.7 (I hope - I'm quoting an email exchange I had on this topic with Eric Lippert a while ago):
Signed and unsigned integral primitive
types can be assigned to each other;
e.g., int8 := uint8 is valid. For this
purpose, bool shall be considered
compatible withuint8
and vice versa,
which makesbool := uint8
valid, and
vice versa. This is also true for
arrays of signed and unsigned integral
primitive types of the same size;
e.g.,int32[] := uint32[]
is valid.
(I haven't checked, but I assume that this sort of reference type conversion being valid is what makes is
return true as well.)
It's somewhat unfortunate that there are disconnects between the language and the underlying execution engine, but it's pretty much unavoidable in the long run, I suspect. There are a few other cases like this, but the good news is that they rarely seem to cause significant harm.
EDIT: As Marc deleted his answer, I've linked to the full mail from Eric, as posted to the C# newsgroup.
Why does Random.Next() return an int instead of uint?
uint is not CLS-Compliant.
Here is some great reading on the topic:
http://msdn.microsoft.com/en-us/library/vstudio/bhc3fa7f(v=vs.100).aspx
Why does this implicit conversion from int to uint work?
Integer constant conversions are treated as very special by the C# language; here's section 6.1.9 of the specification:
A constant expression of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type. A constant expression of type long can be converted to type ulong, provided the value of the constant expression is not negative.
This permits you to do things like:
byte x = 64;
which would otherwise require an ugly explicit conversion:
byte x = (byte)64; // gross
Why does typeof(IList uint ).IsAssignableFrom(typeof(int[]) return true?
It is assignable because it works if you cast explicitly:
IList<UInt16> x = (IList<UInt16>)(IList)new Int16[] { };
So you just can't let it cast implictly to the target type.
why is a cast from
IList
toList<UInt16>
valid but a cast fromIList
toIList<UInt32>
invalid?
Before i start to explain it in my words, read Jon Skeets answer:
You can't directly cast between
int[]
anduint[]
in C# because the
language doesn't believe any conversion is available. However, if you
go via object(*orIList
in my example) the result is up to the CLI.
CLI spec section 8.7
Signed and unsigned integral primitive types can be assigned to each
other; e.g.,int8 := uint8
is valid. For this purpose,bool
shall be
considered compatible withuint8
and vice versa, which makes bool :=
uint8 valid, and vice versa. This is also true for arrays of signed
and unsigned integral primitive types of the same size; e.g.,int32[] := uint32[]
is valid.
C# object equals int doesn't equal true
Since Equals
is a virtual method it will call the appropriate method of the subclass of object
. In this case int.Equals
. In a very simple example:
object o = 4;
int i = 4;
o.Equals(i)
returns true
. So your problem is somewhere else. Maybe objectValue is not an int
, but a byte
, short
or other numerical type.
Why does casting a value as IEnumerable T behave differently based on how I initialized the value?
I think that's because of unusual differences between how C# and CLR treats conversions between int
and uint
, as described in this answer. First note that this code won't compile:
uint[] a1 = new[] { 1u };
var a2 = (int[])a1;
Because C# doesn't believe there exists a cast. However if you go this way:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
Runtime will decide if this cast is valid or not, and it (CLR) thinks differently and allows casting from uint[]
to int[]
(and visa versa), as desribed in answer I linked.
But the same is not true for List<int>
and List<uint>
- they are not treated in a special way by CLR and as such cannot be cast between each other.
So in your case, uint[]
can be cast to int[]
and int[]
implements IEnumerable<int>
, so your idList
is not null. This is not true for Lists - hence your problem.
As for why ToList fails in first case, that's because internally it does something like that:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
// ToList copies contents to new array
int[] copy = new int[a2.Length];
Array.Copy(a2, copy, a2.Length);
And Array.Copy
checks directly if type of elements in one array are compatible with type of elements in another array.
Boolean int conversion issue
There is no implicit conversion of a bool
to an int
. Only an explicit one:
Convert.ToInt32(someBool)
// or...
someBool ? 1 : 0
From that site you linked:
First, you cannot implicitly convert from bool to int. The C# compiler uses this rule to enforce program correctness. It is the same rule that mandates you cannot test an integer in an if statement.
Edit
int
doesn't have a concept of infinity. Only float
and double
do. This means it won't be related to that parameter, unless that parameter just controls the flow of the code that is actually crashing. Which still means it isn't the conversion causing the problem.
You're getting a different error for int.Parse("false")
because it is expecting a number, not a true/false value. This will always throw an exception at runtime, but it will throw in your code, not in the library's code.
I'm starting to think it is the second parameter, contract
, for which you've supplied AUDUSD
.
Related Topics
How to Call a Vbscript File in a C# Application
How to Get Command Line Arguments of Other Processes from .Net/C#
How to Kill a Process Using Vb.Net or C#
Bind to Selecteditems from Datagrid or Listbox in Mvvm
"Invalid JSON Primitive" in Ajax Processing
Wpf: Binding a Contextmenu to an Mvvm Command
Read Connection String from Web.Config
Replace Multiple String Elements in C#
Deserializing into a List Without a Container Element in Xml
Simple State MAChine Example in C#
Entity Framework Self Referencing Loop Detected