Properties should not return arrays
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
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
using System;
namespace PerformanceLibrary
{
public class Book
{
private string[] _Pages;
public Book(string[] pages)
{
_Pages = pages;
}
public string[] Pages
{
get { return _Pages; }
}
}
}
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
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
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();
}
}
}
Return a Collection Example
Description
The following example fixes the violation by changing the property to return a
ReadOnlyCollection.
Code
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
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; }
}
}
}
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
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
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; }
}
}
}
Comments
The following example fixes the violation by changing the property to return a Collection.
Code
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
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; }
}
}
}