Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CA2000 Warning That Can Be Removed By Commenting out Seemingly Unrelated Code

The issue is that VS2010 Code Analysis is returning two CA2000 warnings for a particular function. I haven't been successful at reproducing the warnings with a smaller block of code, so I've posted the original function in it's entirety.

public int SaveTransaction( Transaction tx, UserAccount account ) {

        if ( tx == null ) {
            throw new ArgumentNullException( "tx" );
        }

        if ( account == null ) {
            throw new ArgumentNullException( "account" );
        }

        bool isRefund = tx.TransactionType == LevelUpTransaction.TransactionTypes.Refund;

        int pnRef = 0;

        using ( SqlConnection conn = new SqlConnection( DatabaseConfiguration.ConnectionString ) ) {

            using ( SqlCommand cmd = new SqlCommand( "dbo.SaveTransaction", conn ) ) {

                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add( "@InvoiceId", SqlDbType.VarChar, 100 ).Value = tx.InvoiceNumber;
                cmd.Parameters.Add( "@TxStartDate", SqlDbType.DateTime ).Value = tx.TransactionBeginDate;
                cmd.Parameters.Add( "@AuthDate", SqlDbType.DateTime ).Value = tx.AuthenticationDate;
                cmd.Parameters.Add( "@MerchantKey", SqlDbType.Int ).Value = account.MerchantKey;
                cmd.Parameters.Add( "@UserName", SqlDbType.Char, 25 ).Value = account.UserName;
                cmd.Parameters.Add( "@RegisterNumber", SqlDbType.Char, 10 ).Value = tx.RegisterNumber;
                cmd.Parameters.Add( "@ResellerKey", SqlDbType.Int ).Value = account.ResellerKey;
                cmd.Parameters.Add( "@TxEndDate", SqlDbType.DateTime ).Value = tx.TransactionEndDate;
                cmd.Parameters.Add( "@IpAddress", SqlDbType.VarChar, 15 ).Value = account.IPAddress;
                cmd.Parameters.Add( "@CustomerId", SqlDbType.VarChar, 50 ).Value = tx.CustomerId;
                cmd.Parameters.Add( "@TransactionId", SqlDbType.VarChar, 50 ).Value = tx.TransactionId;
                cmd.Parameters.Add( "@ProcStartDate", SqlDbType.DateTime ).Value = tx.ProcessorBeginDate;
                cmd.Parameters.Add( "@ProcEndDate", SqlDbType.DateTime ).Value = tx.ProcessorEndDate;
                cmd.Parameters.Add( "@AuthAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.OriginalAmount );
                cmd.Parameters.Add( "@ResultCode", SqlDbType.VarChar, 50 ).Value = tx.ResultCode;
                cmd.Parameters.Add( "@ResultMessage", SqlDbType.VarChar, 150 ).Value = tx.ResultMessage;
                cmd.Parameters.Add( "@PONumber", SqlDbType.VarChar, 100 ).Value = tx.PurchaseOrderNumber;
                cmd.Parameters.Add( "@TaxAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.TaxAmount );
                cmd.Parameters.Add( "@Refund", SqlDbType.Bit ).Value = isRefund;

                if ( tx.Order != null ) {
                    cmd.Parameters.Add( "@HostDate", SqlDbType.VarChar, 50 ).Value = tx.Order.HostTime.ToString();
                    cmd.Parameters.Add( "@ApprovalCode", SqlDbType.VarChar, 50 ).Value = tx.Order.TransactionId.ToString( CultureInfo.InvariantCulture );
                    cmd.Parameters.Add( "@NameOnCard", SqlDbType.VarChar, 200 ).Value = tx.Order.UserFirstName + " " + tx.Order.UserLastNameInitial;
                    cmd.Parameters.Add( "@TipAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.Tip.FormattedAmount );
                    cmd.Parameters.Add( "@TotalAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.TotalAmount.FormattedAmount );
                    cmd.Parameters.Add( "@DiscountAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.CreditAmount.FormattedAmount );
                }

                else  {
                    cmd.Parameters.Add( "@NameOnCard", SqlDbType.VarChar, 200 ).Value = DBNull.Value;
                    cmd.Parameters.Add( "@HostDate", SqlDbType.VarChar, 50 ).Value = DBNull.Value;
                    cmd.Parameters.Add( "@ApprovalCode", SqlDbType.VarChar, 50 ).Value = DBNull.Value;
                    cmd.Parameters.Add( "@TipAmount", SqlDbType.Money ).Value = 0;
                    cmd.Parameters.Add( "@TotalAmount", SqlDbType.Money ).Value = 0;
                    cmd.Parameters.Add( "@DiscountAmount", SqlDbType.Money ).Value = 0;
                }

                if ( isRefund ) {
                    cmd.Parameters.Add( "@OriginalPnRef", SqlDbType.Int ).Value = tx.OriginalToken;
                }

                conn.Open();

                using ( SqlDataReader dr = cmd.ExecuteReader() ) {

                    while ( dr.Read() ) {
                        pnRef = SqlNull.Integer( dr["TRX_HD_Key"] );
                    }
                }
            }

        }

        return pnRef;
    }

The two CA2000 warnings pertain to the using statements containing the SqlConnection and SqlCommand.

I can't find any issues in the code itself, but I have found that commenting out lines at random will make the errors go away. For instance, commenting out the three money fields being set to 0 in the else block will remove the warnings. Conversely, commenting out just the three lines with DBNull.Value at the end will remove the error too. I can't make sense of the results.

like image 365
DJ Quimby Avatar asked Oct 08 '22 12:10

DJ Quimby


1 Answers

This has been reported on Microsoft Connect as a possible bug in the analyzer. Apparently, if a using statement contains a lot of code this message is reported erroneously.

It can be suppressed with:

[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Reliability", "CA2000:Dispose objects before losing scope" )]
like image 141
arx Avatar answered Oct 21 '22 07:10

arx