Condividi tramite


Non ignorare i risultati dei metodi

Aggiornamento: novembre 2007

TypeName

DoNotIgnoreMethodResults

CheckId

CA1806

Categoria

Microsoft.Usage

Breaking Change

Non sostanziale

Causa

Viene creato un nuovo oggetto, ma non viene mai utilizzato.

-oppure-

Viene chiamato un metodo per la creazione e la restituzione di una nuova stringa e la nuova stringa non viene mai utilizzata.

-oppure-

Un metodo COM o P/Invoke per la restituzione di un codice di errore o HRESULT che non viene mai utilizzato.

Descrizione della regola

Questa regola consente di informare l'utente di circostanze quali le seguenti quando si verificano nel codice:

  • La creazione di oggetti superflui e la Garbage Collection associata per l'oggetto non utilizzato influiscono negativamente sulle prestazioni.

  • Le stringhe non sono modificabili. Metodi quali ToUpper restituiscono una nuova istanza di una stringa anziché modificare l'istanza della stringa nel metodo chiamante.

  • Se si ignora il codice di errore o HRESULT si rischia di causare un comportamento imprevisto in caso di errore o a una condizione di risorse limitate.

Correzione delle violazioni

Se con il metodo A viene creata una nuova istanza dell'oggetto B che non viene mai utilizzata, passare l'istanza come un argomento a un altro metodo o assegnare l'istanza a una variabile. Se la creazione dell'oggetto non è necessaria, rimuoverla.

-oppure-

Il metodo A chiama il metodo B, ma non utilizza la nuova istanza della stringa restituita dal metodo B. Passare l'istanza come argomento a un altro metodo, assegnare l'istanza a una variabile oppure rimuovere la chiamata se non è necessaria.

-oppure-

Il metodo A chiama il metodo B, ma il codice di errore o HRESULT restituito dal metodo non viene utilizzato. Utilizzare il risultato in un'istruzione condizionale, assegnare il risultato a una variabile o passarlo come argomento a un altro metodo.

Esclusione di avvisi

Non escludere un avviso da questa regola a meno che l'atto di creazione dell'oggetto non abbia uno scopo preciso.

Esempio

Nell'esempio riportato di seguito viene illustrata una classe che ignora il risultato della chiamata a Trim.

Imports System

Namespace Samples

    Public Class Book

        Private ReadOnly _Title As String

        Public Sub New(ByVal title As String)

            If title IsNot Nothing Then
                ' Violates this rule                
                title.Trim()
            End If

            _Title = title

        End Sub

        Public ReadOnly Property Title() As String
            Get
                Return _Title
            End Get
        End Property

    End Class

End Namespace
using System;

namespace Samples
{
    public class Book
    {
        private readonly string _Title;

        public Book(string title)
        {
            if (title != null)
            {
                // Violates this rule                
                title.Trim();
            }

            _Title = title;
        }

        public string Title
        {
            get { return _Title; }
        }
    }
}
using namespace System;

namespace Samples
{
    public ref class Book   
    { 
        private:        
            initonly String^ _Title;

        public:
        Book(String^ title)        
        {               
            if (title != nullptr)            
            {                  
                // Violates this rule                
                title->Trim();            
            }
                _Title = title;        
            }

        property String^ Title        
        {            
            String^ get() { return _Title; }        
        }    
    };
}

Nell'esempio riportato di seguito viene risolta la precedente violazione mediante l'assegnazione del risultato del metodo Trim alla variabile su cui era stata effettuata la chiamata.

Imports System

Namespace Samples

    Public Class Book

        Private ReadOnly _Title As String

        Public Sub New(ByVal title As String)

            If title IsNot Nothing Then
                title = title.Trim()
            End If

            _Title = title

        End Sub

        Public ReadOnly Property Title() As String
            Get
                Return _Title
            End Get
        End Property

    End Class

End Namespace
using System;

namespace Samples
{
    public class Book
    {
        private readonly string _Title;

        public Book(string title)
        {
            if (title != null)
            {
                title = title.Trim();
            }

            _Title = title;
        }

        public string Title
        {
            get { return _Title; }
        }
    }
}
using namespace System;

namespace Samples
{    
    public ref class Book    
    {    
    private:        
        initonly String^ _Title;

    public:
        Book(String^ title)        
        {               
            if (title != nullptr)            
            {                        
                title = title->Trim();            
            }

            _Title = title;        
        }

        property String^ Title        
        {            
            String^ get() { return _Title; }        
        }    
    };
}

Nell'esempio riportato di seguito viene illustrato un metodo che non utilizza un oggetto creato dal metodo stesso.

Nota:

Questa violazione non può essere riprodotta in Visual Basic.

using System;

namespace Samples
{
    public class Book
    {
        public Book()
        {
        }

        public static Book CreateBook()
        {
            // Violates this rule            
            new Book();
            return new Book();
        }
    }
}
using namespace System;

namespace Samples
{    
    public ref class Book    
    {
    public:
        Book()        
        {        
        }

        static Book^ CreateBook()        
        {
            // Violates this rule            
            gcnew Book();            
            return gcnew Book();        
        }    
    };
}

Nell'esempio riportato di seguito viene risolta la precedente violazione mediante la rimozione della creazione non necessaria di un oggetto.

using System;

namespace Samples
{
    public class Book
    {
        public Book()
        {
        }

        public static Book CreateBook()
        {
            return new Book();
        }
    }
}
using namespace System;

namespace Samples
{
    public ref class Book    
    {
    public:
        Book()        
        {           
        }
        static Book^ CreateBook()        
        {            
            return gcnew Book();        
        }            
    };
}

Nell'esempio riportato di seguito viene illustrato un metodo che ignora il codice di errore restituito dal metodo nativo GetShortPathName.

Imports System
Imports System.ComponentModel
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text

Namespace Samples

    Public Module FileIO

        Public Function GetShortPath(ByVal longPath As String) As String

            longPath = Path.GetFullPath(longPath)

            Const MAX_PATH As Integer = 260

            Dim shortPathBuffer As New StringBuilder(MAX_PATH)

            ' Violates this rule
            NativeMethods.GetShortPathName(longPath, shortPathBuffer, shortPathBuffer.Capacity)

            Return shortPathBuffer.ToString()

        End Function

    End Module

    Friend Module NativeMethods

        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True, BestFitMapping:=False, ThrowOnUnmappableChar:=True)> _
        Public Function GetShortPathName(ByVal lpszLongPath As String, ByVal lpszShortPath As StringBuilder, ByVal cchBuffer As UInteger) As UInteger
        End Function

    End Module

End Namespace

using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Samples
{
    public static class FileIO
    {
        public static string GetShortPath(string longPath)
        {
            longPath = Path.GetFullPath(longPath);

            const int MAX_PATH = 260;

            StringBuilder shortPathBuffer = new StringBuilder(MAX_PATH);

            // Violates this rule
            NativeMethods.GetShortPathName(longPath, shortPathBuffer, (uint)shortPathBuffer.Capacity);

            return shortPathBuffer.ToString();
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
        public static extern uint GetShortPathName(string lpszLongPath, StringBuilder lpszShortPath, uint cchBuffer);
    }
}
#include "stdafx.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
using namespace System::Text;

namespace Samples
{
    private ref class NativeMethods sealed
    {
    private:
        NativeMethods()
        {
        }

    internal:

        [DllImport("kernel32.dll", CharSet=CharSet::Auto, SetLastError=true, BestFitMapping=false, ThrowOnUnmappableChar=true)]
        static unsigned int GetShortPathName(String^ lpszLongPath, StringBuilder^ lpszShortPath, unsigned int cchBuffer);
    };
    
    public ref class FileIO sealed
    {
    private:
        FileIO()
        {
        }

    public:
        static String^ GetShortPath(String^ longPath)
        {
            longPath = Path::GetFullPath(longPath);

            const int MAX_PATH = 260;

            StringBuilder^ shortPathBuffer = gcnew StringBuilder(MAX_PATH);

            // Violates this rule
            NativeMethods::GetShortPathName(longPath, shortPathBuffer, shortPathBuffer->Capacity);

            return shortPathBuffer->ToString();
        }
    };
}

Nell'esempio riportato di seguito viene risolta la precedente violazione mediante il controllo del codice di errore e la generazione di un'eccezione quando la chiamata ha esito negativo.

Namespace Samples

    Public Module FileIO_1

        Public Function GetShortPath(ByVal longPath As String) As String

            longPath = Path.GetFullPath(longPath)

            Const MAX_PATH As Integer = 260

            Dim shortPathBuffer As New StringBuilder(MAX_PATH)

            ' GetShortPathName returns 0 when the operation fails
            If NativeMethods.GetShortPathName(longPath, shortPathBuffer, shortPathBuffer.Capacity) = 0 Then

                ' Note: The constructor of Win32Exception will automatically
                ' set Win32Exception.NativeErrorCode to Marshal.GetLastWin32Error()
                Throw New Win32Exception()

            End If

            Return shortPathBuffer.ToString()

        End Function

    End Module

    Friend Module NativeMethods_1

        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True, BestFitMapping:=False, ThrowOnUnmappableChar:=True)> _
        Public Function GetShortPathName(ByVal lpszLongPath As String, ByVal lpszShortPath As StringBuilder, ByVal cchBuffer As UInteger) As UInteger
        End Function

    End Module

End Namespace
namespace Samples
{
    public static class FileIO_1
    {
        public static string GetShortPath(string longPath)
        {
            const int MAX_PATH = 260;

            StringBuilder shortPathBuffer = new StringBuilder(MAX_PATH);

            // GetShortPathName returns 0 when the operation fails
            if (NativeMethods.GetShortPathName(longPath, shortPathBuffer, (uint)shortPathBuffer.Capacity) == 0)
            {
                // Note: The constructor of Win32Exception will automatically
                // set Win32Exception.NativeErrorCode to Marshal.GetLastWin32Error()
                throw new Win32Exception();
            }

            return shortPathBuffer.ToString();
        }
    }

    internal static class NativeMethods_1
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
        public static extern uint GetShortPathName(string lpszLongPath, StringBuilder lpszShortPath, uint cchBuffer);
    }
}
#include "stdafx.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
using namespace System::Text;

namespace Samples
{
    private ref class NativeMethods_1 sealed
    {
    private:
        void NativeMethods()
        {
        }

    internal:

        [DllImport("kernel32.dll", CharSet=CharSet::Auto, SetLastError=true, BestFitMapping=false, ThrowOnUnmappableChar=true)]
        static unsigned int GetShortPathName(String^ lpszLongPath, StringBuilder^ lpszShortPath, unsigned int cchBuffer);
    };
    
    public ref class FileIO_1 sealed
    {
    private:
        void FileIO()
        {
        }

    public:
        static String^ GetShortPath(String^ longPath)
        {
            longPath = Path::GetFullPath(longPath);

            const int MAX_PATH = 260;

            StringBuilder^ shortPathBuffer = gcnew StringBuilder(MAX_PATH);

             // GetShortPathName returns 0 when the operation fails
            if (NativeMethods::GetShortPathName(longPath, shortPathBuffer, shortPathBuffer->Capacity) == 0)
            {
                // Note: The constructor of Win32Exception will automatically
                // set Win32Exception.NativeErrorCode to Marshal.GetLastWin32Error()
                throw gcnew Win32Exception();
            }


            return shortPathBuffer->ToString();
        }
    };
}