CA1011: Consider passing base types as parameters
Item | Value |
---|---|
RuleId | CA1011 |
Category | Microsoft.Design |
Breaking change | Breaking |
Cause
A method declaration includes a formal parameter that is a derived type, and the method calls only members of the base type of the parameter.
Rule description
When a base type is specified as a parameter in a method declaration, any type that is derived from the base type can be passed as the corresponding argument to the method. When the argument is used inside the method body, the specific method that is executed depends on the type of the argument. If the additional functionality that is provided by the derived type is not required, use of the base type allows wider use of the method.
How to fix violations
To fix a violation of this rule, change the type of the parameter to its base type.
When to suppress warnings
It is safe to suppress a warning from this rule
if the method requires the specific functionality that is provided by the derived type
- or -
to enforce that only the derived type, or a more derived type, is passed to the method.
In these cases, the code will be more robust because of the strong type checking that is provided by the compiler and runtime.
Example
The following example shows a method, ManipulateFileStream
, that can be used only with a FileStream object, which violates this rule. A second method, ManipulateAnyStream
, satisfies the rule by replacing the FileStream parameter by using a Stream.
using System;
using System.IO;
namespace DesignLibrary
{
public class StreamUser
{
int anInteger;
public void ManipulateFileStream(FileStream stream)
{
while ((anInteger = stream.ReadByte()) != -1)
{
// Do something.
}
}
public void ManipulateAnyStream(Stream anyStream)
{
while ((anInteger = anyStream.ReadByte()) != -1)
{
// Do something.
}
}
}
class TestStreams
{
static void Main()
{
StreamUser someStreamUser = new StreamUser();
MemoryStream testMemoryStream = new MemoryStream(new byte[] { });
using (FileStream testFileStream =
new FileStream("test.dat", FileMode.OpenOrCreate))
{
// Cannot be used with testMemoryStream.
someStreamUser.ManipulateFileStream(testFileStream);
someStreamUser.ManipulateAnyStream(testFileStream);
someStreamUser.ManipulateAnyStream(testMemoryStream);
}
}
}
}