CA1819: Properties should not return arrays

Note

This article applies to Visual Studio 2015. If you're looking for Visual Studio 2017 documentation, use the version selector at the top left. We recommend upgrading to Visual Studio 2017. Download it here.

TypeName PropertiesShouldNotReturnArrays
CheckId CA1819
Category Microsoft.Performance
Breaking Change Breaking

Cause

A public or protected property in a public type returns an array.

Rule Description

Arrays returned by properties are not write-protected, even if the property is read-only. To keep the array tamper-proof, the property must return a copy of the array. Typically, users will not understand the adverse performance implications of calling such a property. Specifically, they might use the property as an indexed property.

How to Fix Violations

To fix a violation of this rule, either make the property a method or change the property to return a collection.

When to Suppress Warnings

Attributes can contain properties that return arrays, but cannot contain properties that return collections. You can suppress a warning that is raised for a property of an attribute that is derived from the [System.Attribute]() class. Otherwise, do not suppress a warning from this rule.

Example Violation

Description

The following example shows a property that violates this rule.

Code

using System; 

namespace PerformanceLibrary
{    
    public class Book    
    {        
        private string[] _Pages;      
           
        public Book(string[] pages)        
        {            
            _Pages = pages;        
        }         
        
        public string[] Pages        
        {            
            get { return _Pages; }        
        }    
    }
}
Imports System 

Namespace PerformanceLibrary     

    Public Class Book         
        
        Private _Pages As String()       
          
        Public Sub New(ByVal pages As String())  
            _Pages = pages        
        End Sub         
        
        Public ReadOnly Property Pages() As String()            
            Get                
                Return _Pages            
            End Get            
        End Property     
        
    End Class 
    
End Namespace

Comments

To fix a violation of this rule, either make the property a method or change the property to return a collection instead of an array.

Change the Property to a Method Example

Description

The following example fixes the violation by changing the property to a method.

Code

using System; 

namespace PerformanceLibrary
{    
    public class Book    
    {        
        private string[] _Pages;         
        
        public Book(string[] pages)        
        {            
            _Pages = pages;        
        }         
        
        public string[] GetPages()        
        {            
            // Need to return a clone of the array so that consumers            
            // of this library cannot change its contents            
            return (string[])_Pages.Clone();        
        }    
    }
}
Imports System 

Namespace PerformanceLibrary     

    Public Class Book         
    
        Private _Pages As String()         
        
        Public Sub New(ByVal pages As String())            
            _Pages = pages        
        End Sub         
        
        Public Function GetPages() As String()	    
            ' Need to return a clone of the array so that consumers            
            ' of this library cannot change its contents            
            Return DirectCast(_Pages.Clone(), String())        
        End Function     
        
    End Class 
    
End Namespace

Return a Collection Example

Description

The following example fixes the violation by changing the property to return a

System.Collections.ObjectModel.ReadOnlyCollection<T>.

Code

using System;
using System.Collections.ObjectModel; 

namespace PerformanceLibrary
{    
    public class Book    
    {        
        private ReadOnlyCollection<string> _Pages;         
        public Book(string[] pages)        
        {            
            _Pages = new ReadOnlyCollection<string>(pages);        
        }         
        
        public ReadOnlyCollection<string> Pages        
        {            
            get { return _Pages; }        
        }    
    }
}
Imports System
Imports System.Collections.ObjectModel 

Namespace PerformanceLibrary     

    Public Class Book         
    
        Private _Pages As ReadOnlyCollection(Of String)         
        
        Public Sub New(ByVal pages As String())            
            _Pages = New ReadOnlyCollection(Of String)(pages)        
        End Sub         
        
        Public ReadOnly Property Pages() As ReadOnlyCollection(Of String)            
            Get                
                Return _Pages            
            End Get        
        End Property     
        
    End Class 
    
End Namespace

Allowing Users to Modify a Property

Description

You might want to allow the consumer of the class to modify a property. The following example shows a read/write property that violates this rule.

Code

using System; 

namespace PerformanceLibrary
{    
    public class Book    
    {        
        private string[] _Pages;         
        
        public Book(string[] pages)        
        {            
            _Pages = pages;        
        }         
        
        public string[] Pages        
        {            
            get { return _Pages; }            
            set { _Pages = value; }        
        }    
    }
}
Imports System 

Namespace PerformanceLibrary     

    Public Class Book         
    
        Private _Pages As String()         
        
        Public Sub New(ByVal pages As String())            
            _Pages = pages        
        End Sub         
        
        Public Property Pages() As String()            
            Get                
                Return _Pages            
            End Get            
            
            Set(ByVal value as String())                
                _Pages = value            
            End Set        
        End Property     
        
    End Class 

End Namespace

Comments

The following example fixes the violation by changing the property to return a System.Collections.ObjectModel.Collection<T>.

Code

using System;
using System.Collections.ObjectModel; 

namespace PerformanceLibrary
{    
    public class Book    
    {        
        private Collection<string> _Pages;         
        
        public Book(string[] pages)        
        {            
            _Pages = new Collection<string>(pages);        
        }         
        
        public Collection<string> Pages        
        {            
            get { return _Pages; }        
        }    
    }
}
Imports System
Imports System.Collections.ObjectModel 

Namespace PerformanceLibrary     

    Public Class Book         
    
        Private _Pages As Collection(Of String)         
        
        Public Sub New(ByVal pages As String())            
            _Pages = New Collection(Of String)(pages)        
        End Sub         
        
        Public ReadOnly Property Pages() As Collection(Of String)            
            Get                
                Return _Pages            
            End Get        
        End Property     
        
    End Class 

End Namespace

CA1024: Use properties where appropriate