代码改变世界

[FxCop.设计规则]8. 也许参数类型应该是基类型

2005-06-07 21:45  Colin Han  阅读(1553)  评论(0编辑  收藏  举报

8.     也许参数类型应该是基类型

翻译概述:

这条规则中,微软建议为了提高代码的可重用性,如果可能,尽量将参数类型修改为它的基类型。但是,这条规则并不是一条强制规则,在最后,微软提到,如果需要,使用子类型作为参数可以提高代码的健壮性。

关于这一点,译者比较趋向于尽量使用子类型作参数的类型,因为这样可以减少函数被滥用的情况(个人认为滥用比起重用的优先级更高一下)。而且,如果将来发现确实需要,我们可以通过简单的重构来达到提高重用性的目的。

原文引用:

Consider passing base types as parameters

TypeName:

ConsiderPassingBaseTypesAsParameters

CheckId:

CA1011

Category:

Microsoft.Design

Message Level:

Error

Certainty:

75%

Breaking Change:

Breaking


Cause: A method declaration includes a formal parameter that is a derived type, and the method only calls members of the parameter's base type.

Rule Description

When a base type is specified as a parameter in a method declaration, any type 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 provided by the derived type is not required, use of the base type allows the method to be more widely utilized.

How to Fix Violations

To fix a violation of this rule, change the type of the parameter to its base type.

When to Exclude Messages

It is safe to exclude a message from this rule if the method requires the specific functionality provided by the derived type or to enforce that only the derived type, or a more derived type, is passed to the method. In this case, the code will be more robust because of the strong type checking provided by the compiler and runtime.

Example Code

The following example shows a method, ManipulateFileStream, that can only be used with a FileStream object, which violates this rule. A second method, ManipulateAnyStream, satisfies the rule by replacing the FileStream parameter with a Stream.

[C#]

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);
         }

      }

   }

}


Related Rules

Members should not expose certain concrete types

 

引起的原因:

一个方法包含一个子类型的形参,但是方法内部仅仅使用了基类型中的成员。

描述:

如果一个方法的参数使用基类型,可以使用任何一个继承自这个基类型的类型作为参数调用这个函数。在一个方法内部使用一个类型,表示这个方法的执行依赖于这个参数的类型。如果不需要使用子类型所扩展的功能,使用基类型使方法可以被更广泛的使用。

修复:

修改参数类型为它的基类型。

例外:

如果这个方法需要扩展的功能,或需要强制只有指定的一个或多个子类型可以使用这个方法,这条规则可以忽略。这种情况下,代码还会更加的健壮。因为编译和运行时进行了强的类型检查。