I had to come up with a quick routine and tossed it off in VB. The guy working on the project is a C# dude. I used the reflector to get c# code for him and noticed some very bad things in the output. Is this an issue with the disassembly output by Reflector or is this goofyness winding up in production?

The original:
Public Function CalculateCheckDigitVB(ByVal Input As String) As String
        Dim _temp As String = Input.Trim.ToUpper
        Dim _digitTest As String = String.Empty
        Dim _sum As Integer = 0
        Dim _weight As Integer = 0
        Dim _digit As Integer = 0
        If _temp = String.Empty Then
            Return String.Empty
        End If
        _temp = _temp.PadLeft(17, "0"c)
        For _index As Integer = 0 To 16
            _digitTest = _temp.Substring(_index, 1)
            Select Case _digitTest
                Case "0" To "9"
                    'OK
                    _digit = CInt(_digitTest)
                Case Else
                    Return String.Empty
            End Select
            _weight = CInt(IIf(_index Mod 2 = 0, 3, 1))
            _digit = _digit * _weight
            _sum += _digit
        Next
        _sum = _sum Mod 10
        Dim _check As Integer = 10 - _sum
        Return CStr(_check Mod 10)
    End Function
Here is the C# from the reflector:
public static string CalculateCheckDigitVB(string Input)
{
    int VB$CG$t_i4$S0;
    string _temp = Input.Trim().ToUpper();
    string _digitTest = string.Empty;
    int _sum = 0;
    int _weight = 0;
    int _digit = 0;
    if (_temp == string.Empty)
    {
        return string.Empty;
    }
    _temp = _temp.PadLeft(0x11, '0');
    int _index = 0;
    do
    {
        _digitTest = _temp.Substring(_index, 1);
        string VB$t_string$L0 = _digitTest;
        if ((((Operators.CompareString(VB$t_string$L0, "0", false) >= 0) && (Operators.CompareString(VB$t_string$L0, "9", false) <= 0)) ? 1 : 0) != 0)
        {
            _digit = Conversions.ToInteger(_digitTest);
        }
        else
        {
            return string.Empty;
        }
        _weight = Conversions.ToInteger(Interaction.IIf((_index % 2) == 0, 3, 1));
        _digit *= _weight;
        _sum += _digit;
        _index++;
        VB$CG$t_i4$S0 = 0x10;
    }
    while (_index <= VB$CG$t_i4$S0);
    _sum = _sum % 10;
    int _check = 10 - _sum;
    return Conversions.ToString((int) (_check % 10));
}

Note the VB$CG$t_i4$S0 = 0x10; inside the loop! O.M.G. Then the fact that someting turned my perfectly good FOR / NEXT loop into a while loop ticked me off. If it was a good while loop I would not have cared.

Then there is:
_digitTest = _temp.Substring(_index, 1);
        string VB$t_string$L0 = _digitTest;
Why this oddly named extra string object for just the range test when there is a perfectly good one right above. I'm having memory issues with perfectly good code on the mobile. Code this be part of that? Namely these objects created internally are doing it to me when we have spent hours reviewing every object and its disposal.
Charles Kincaid
0

Comments

2 comments

  • haleyjason
    The differences you are noting really are just part of the decompiling problem.

    Reflector is working with the IL backwards, so it is trying to find patterns that make sense ... often times this introduces new temp variable names (those ugly names you refer to are just temps that were not originally in your code) and loops morphing in to more simple do/while loops ... in IL it is very hard to determine the difference between a for and a while loop since they get compiled to conditionals and branch (goto) code.
    haleyjason
    0
  • Charles Kincaid
    Thanks for that. I often get asked about the merits of differnt .net languages. The benchamarks I had done years ago showed that here were no performance benifits one way or the other. I thought that I might have stumbled on something that could push VB into the grave.

    Our team members that use both C# and VB state that the IDE on the Basic side is way better that the C# one. I was looking for a better excuse to shed VB.

    So it's the FOR / NEXT compiler on both sides that causes this repeated initialization of the loop control variable? OK. I'll pass that on to our C# members. On Mobile devices we have to wring out the last ounce of performance.
    Charles Kincaid
    0

Add comment

Please sign in to leave a comment.