Parameter Design

The guidelines in this topic help you select the correct types and names for member parameters. The following topics also present design guidelines for parameters.

Do use the least-derived parameter type that provides the functionality required by the member.

The following code example illustrates this guideline. The BookInfo class inherits from the Publication class. The Manager class implements two methods: BadGetAuthorBiography and GoodGetAuthorBiography. BadGetAuthorBiography uses references to BookInfo objects even though it uses only members declared in Publication. The GoodGetAuthorBiography method demonstrates the correct design.

' A Class with some basic information.
Public Class Publication
    Dim Protected authorValue as String
    Dim Protected publicationDateValue as DateTime

    Public Sub new(author as String, publishDate as DateTime)
        Me.authorValue = author
        Me.PublicationDateValue = publishDate
    End Sub

    Public Readonly Property  PublicationDate as DateTime 
        Get
            Return publicationDateValue
        End Get
    End Property

    Public Readonly Property Author as String
        Get 
            Return authorValue
        End Get
    End Property
End Class

' A Class that derives from Publication
Public Class BookInfo 
    Inherits Publication

    Dim isbnValue as String

    Public Sub new(author as string, _
        publishDate as DateTime, _
        isbn as String) 
        MyBase.New(author, publishDate)
        Me.isbnValue = isbn
    End Sub

    Public Readonly Property Isbn as String
        Get 
            Return isbnValue
        End Get
    End Property
End Class

Public Class Manager
    ' This method does not use the Isbn member
    ' so it doesn't need a specialized reference to Books
    Shared Function BadGetAuthorBiography(book as BookInfo) as String
        Dim biography as String = ""
        Dim author as String = book.Author
        ' Do work here.
        Return biography
    End Function

    ' This method shows the correct design.
    Shared Function GoodGetAuthorBiography(item as Publication) as String
        Dim biography as String = ""
        Dim author as String = item.Author
        ' Do work here.
        Return biography
    End Function
// A class with some basic information.
public class Publication
{
    string author;
    DateTime publicationDate;

    public Publication(string author, DateTime publishDate)
    {
        this.author = author;
        this.publicationDate = publishDate;
    }
    public DateTime PublicationDate
    {
        get {return publicationDate;}
    }
    public string Author
    {
        get {return author;}
    }
}

// A class that derives from Publication
public class BookInfo :Publication
{
    string isbn;
    public BookInfo(string author, DateTime publishDate, string isbn) :
            base(author, publishDate)
    {
        this.isbn = isbn;
    }
    public string Isbn
    {
        get {return isbn;}
    }
}

public class Manager
{
    // This method does not use the Isbn member
    // so it doesn't need a specialized reference to Books
    static string BadGetAuthorBiography(BookInfo book)
    {
        string biography = "";
        string author = book.Author;
        // Do work here.
        return biography;

    }
    // This method shows the correct design.
    static string GoodGetAuthorBiography(Publication item)
    {
        string biography = "";
        string author = item.Author;
        // Do work here.
        return biography;
    }
// A class with some basic information.
public ref class Publication
{
private:
    String^ author;
    DateTime publicationDate;

public:
    Publication(String^ author, DateTime publishDate)
    {
        this->author = author;
        this->publicationDate = publishDate;
    }

    property DateTime PublicationDate
    {
        DateTime get() {return publicationDate;}
    }

    property String^ Author
    {
        String^ get() {return author;}
    }
};

// A class that derives from Publication
public ref class BookInfo : public Publication
{
private:
    String^ isbn;

public:
    BookInfo(String^ author, DateTime publishDate, String^ isbn) :
            Publication(author, publishDate)
    {
        this->isbn = isbn;
    }

    property String^ Isbn
    {
        String^ get() {return isbn;}
    }
};

private enum class ErrorOptions {ThrowOnError};

private enum class CasingOptions {CaseInsensitive};

private ref class BetterType
{
internal:
    static void GetType(String^ name,
    ErrorOptions throwOption,
    CasingOptions caseOption)
    {}
};

public ref class Manager
{
public:
    // This method does not use the Isbn member
    // so it doesn't need a specialized reference to Books
    static String^ BadGetAuthorBiography(BookInfo^ book)
    {
        String^ biography = "";
        String^ author = book->Author;
        // Do work here.
        return biography;

    }
    // This method shows the correct design.
    static String^ GoodGetAuthorBiography(Publication^ item)
    {
        String^ biography = "";
        String^ author = item->Author;
        // Do work here.
        return biography;
    }

Do not use reserved parameters.

Future versions of a library can add new overloads that take additional parameters.

The following code example first demonstrates an incorrect method that violates this guideline, and then shows methods with the correct design.

    Public Sub BadStoreTimeDifference (localDate as DateTime, _
        toWhere as TimeZone, _
        reserved as Object)
        ' Do work here.
    End Sub

Public Sub GoodCStoreTimeDifference (localDate as DateTime, _
    toWhere as TimeZone)
    ' Do work here.
End Sub

Public Sub GoodCStoreTimeDifference (localDate as DateTime, _
    toWhere as TimeZone, _
    useDayLightSavingsTime as Boolean)
    ' Do work here.
End Sub
    public void BadStoreTimeDifference (DateTime localDate, 
        TimeZone toWhere, 
        Object reserved)
    {
        // Do work here.
    }

public void GoodCStoreTimeDifference (DateTime localDate, 
    TimeZone toWhere)
{
    // Do work here.
}
public void GoodCStoreTimeDifference (DateTime localDate, 
    TimeZone toWhere, 
    bool useDayLightSavingsTime)
{
    // Do work here.
}
void BadStoreTimeDifference(DateTime localDate,
    TimeZone^ toWhere,
    Object^ reserved)
{
    // Do work here.
}

void GoodCStoreTimeDifference(DateTime localDate,
    TimeZone^ toWhere)
{
    // Do work here.
}

void GoodCStoreTimeDifference(DateTime localDate,
    TimeZone^ toWhere,
    bool useDayLightSavingsTime)
{
    // Do work here.
}

Do not use publicly exposed methods that take pointers, arrays of pointers, or multidimensional arrays as parameters.

Knowledge of these advanced features should not be required to use most libraries.

Do place all out parameters after all of the pass-by-value and ref parameters (excluding parameter arrays), even if this results in an inconsistency in parameter ordering between overloads.

This convention makes the method signature easier to understand.

Do be consistent in naming parameters when overriding members or implementing interface members.

Overrides should use the same parameter names. Overloads should use the same parameter names as the declaring member. Interface implementations should use the same names defined in the interface member signature.

Portions Copyright 2005 Microsoft Corporation. All rights reserved.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

For more information on design guidelines, see the "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" book by Krzysztof Cwalina and Brad Abrams, published by Addison-Wesley, 2005.

See Also

Other Resources

Member Design Guidelines

Design Guidelines for Developing Class Libraries