Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - custom explicit conversion with checked/unchecked operator

Tags:

c#

I'm learning to write custom type conversions in C# and I have a question I can't manage to resolve with Google / MSDN / earlier posted SO items.

Normally, a C# program that narrows a numeric type does that via unchecked explicit conversion, e.g.:

int i = 256;
byte b = (byte)i; // b == 0

however, the following will give an overflow exception:

byte b = checked((byte)i);

My question is as follows: is the behavior of the checked / unchecked keyword implementable in an custom type conversion, e.g.:

class Foo {
  public static explicit operator int(Foo bar) {
    if (checked)
      throw someEception
    else
      return some Foo to int conversion
  }
}

Of course, the code above is not the answer, but does anyone know if something like this is possible?

like image 586
Webleeuw Avatar asked Nov 12 '09 17:11

Webleeuw


3 Answers

checked is a compile time thing. That is, its sole effect will be on the code block directly surrounded by a checked statement, not the methods called in that block. Consequently, there wouldn't be a checked and unchecked context at run time that you may want to adjust the behavior of a function according to it.

like image 150
mmx Avatar answered Sep 30 '22 00:09

mmx


Section 14.5.12 of the C# language spec explicitly enumerates all the operators on which the checked and unchecked keywords can have an effect.

User defined operators are not part of that list, so no, you cannot write a user-defined conversion operator that takes checked/unchecked into account.

like image 36
Wim Coenen Avatar answered Sep 29 '22 23:09

Wim Coenen


checked causes a "check for overflow" version of the appropriate CIL instruction to be generated by the compiler.

Here's a dump from IL Disassembler:

//000012:       Int32 i = 42;
  IL_0001:  ldc.i4.s   42
  IL_0003:  stloc.0
//000013:       Byte b1 = (Byte) i;
  IL_0004:  ldloc.0
  IL_0005:  conv.u1
  IL_0006:  stloc.1
//000014:       Byte b2 = checked ((Byte) i);
  IL_0007:  ldloc.0
  IL_0008:  conv.ovf.u1
  IL_0009:  stloc.2
like image 34
Chris R. Timmons Avatar answered Sep 30 '22 01:09

Chris R. Timmons