When a ?:'s two branches have different stack types and ILSpy can't find a common type tighter than object, it hoists the conditional into an if/else with an object obj local — but drops the explicit cast that was present in the source. The dropped cast can re-bind to a different overload on recompile.
Repro
using System.Collections.Generic;
using System.Linq;
public class Repro
{
public IEnumerator<byte> Bug(byte[] data, bool reversed)
=> (reversed ? ((IEnumerable<byte>)data).Reverse() : (IEnumerable<byte>)data).GetEnumerator();
}
ilspycmd 10.0.1.8346 output
public IEnumerator<byte> Bug(byte[] data, bool reversed)
{
object obj;
if (!reversed)
{
obj = data;
}
else
{
obj = data.Reverse(); // (IEnumerable<byte>) cast lost
}
return ((IEnumerable<byte>)obj).GetEnumerator();
}
When a project-local void Reverse(this byte[]) (or similar shadowing extension) is in scope, data.Reverse() re-binds to it on recompile → CS0029 ("Cannot implicitly convert type 'void' to 'object'"). Even without a shadow, the decompile is semantically lossy.
dotPeek emits the inline ternary form with both casts preserved.
Related
#1501, #1614, #3322, #3464, #793 are all in the same family (ILSpy dropping a needed cast); none is exactly this ?:→if/else hoist variant.
When a
?:'s two branches have different stack types and ILSpy can't find a common type tighter thanobject, it hoists the conditional into anif/elsewith anobject objlocal — but drops the explicit cast that was present in the source. The dropped cast can re-bind to a different overload on recompile.Repro
ilspycmd 10.0.1.8346 output
When a project-local
void Reverse(this byte[])(or similar shadowing extension) is in scope,data.Reverse()re-binds to it on recompile → CS0029 ("Cannot implicitly convert type 'void' to 'object'"). Even without a shadow, the decompile is semantically lossy.dotPeek emits the inline ternary form with both casts preserved.
Related
#1501, #1614, #3322, #3464, #793 are all in the same family (ILSpy dropping a needed cast); none is exactly this
?:→if/elsehoist variant.