Func および Action 汎用デリゲートでの分散の使用 (C# および Visual Basic)

以下の例では、Func 汎用デリゲートと Action 汎用デリゲートの共変性と反変性を使用して、メソッドの再利用を可能にし、コードの柔軟性を高める方法を示します。

共変性と反変性の詳細については、「デリゲートの分散 (C# および Visual Basic)」を参照してください。

デリゲートと共変の型パラメーターの使用

次の例は、Func 汎用デリゲートにおける共変性のサポートの利点を示しています。FindByTitle メソッドは、String 型のパラメーターを受け取り、Employee 型のオブジェクトを返します。しかし、このメソッドは Func<String, Person> デリゲート (Visual Basic では Func(Of String, Person)) に割り当てることもできます。これは、Employee が Person を継承するためです。

' Simple hierarchy of classes.
Public Class Person
End Class

Public Class Employee
    Inherits Person
End Class

Class Finder
    Public Shared Function FindByTitle(
        ByVal title As String) As Employee
        ' This is a stub for a method that returns
        ' an employee that has the specified title.
        Return New Employee
    End Function

    Sub Test()
        ' Create an instance of the delegate without using variance.
        Dim findEmployee As Func(Of String, Employee) =
            AddressOf FindByTitle

        ' The delegate expects a method to return Person,
        ' but you can assign it a method that returns Employee.
        Dim findPerson As Func(Of String, Person) =
            AddressOf FindByTitle

        ' You can also assign a delegate 
        ' that returns a more derived type to a delegate 
        ' that returns a less derived type.
        findPerson = findEmployee
    End Sub
End Class
// Simple hierarchy of classes.
public class Person { }
public class Employee : Person { }
class Program
{
    static Employee FindByTitle(String title)
    {
        // This is a stub for a method that returns
        // an employee that has the specified title.
        return new Employee();
    }

    static void Test()
    {
        // Create an instance of the delegate without using variance.
        Func<String, Employee> findEmployee = FindByTitle;

        // The delegate expects a method to return Person,
        // but you can assign it a method that returns Employee.
        Func<String, Person> findPerson = FindByTitle;

        // You can also assign a delegate 
        // that returns a more derived type 
        // to a delegate that returns a less derived type.
        findPerson = findEmployee;

    }
}

デリゲートと反変の型パラメーターの使用

次の例は、Action 汎用デリゲートにおける反変性のサポートの利点を示しています。AddToContacts メソッドは、Person 型のパラメーターを受け取ります。しかし、このメソッドは Action<Employee> デリゲート (Visual Basic では (Action(Of Employee)) に割り当てることもできます。これは、Employee が Person を継承するためです。

Public Class Person
End Class

Public Class Employee
    Inherits Person
End Class

Class AddressBook
    Shared Sub AddToContacts(ByVal person As Person)
        ' This method adds a Person object
        ' to a contact list.
    End Sub

    Sub Test()
        ' Create an instance of the delegate without using variance.
        Dim addPersonToContacts As Action(Of Person) =
            AddressOf AddToContacts

        ' The Action delegate expects 
        ' a method that has an Employee parameter,
        ' but you can assign it a method that has a Person parameter
        ' because Employee derives from Person.
        Dim addEmployeeToContacts As Action(Of Employee) =
            AddressOf AddToContacts

        ' You can also assign a delegate 
        ' that accepts a less derived parameter 
        ' to a delegate that accepts a more derived parameter.
        addEmployeeToContacts = addPersonToContacts
    End Sub
End Class
public class Person { }
public class Employee : Person { }
class Program
{
    static void AddToContacts(Person person)
    {
        // This method adds a Person object
        // to a contact list.
    }

    static void Test()
    {
        // Create an instance of the delegate without using variance.
        Action<Person> addPersonToContacts = AddToContacts;

        // The Action delegate expects 
        // a method that has an Employee parameter,
        // but you can assign it a method that has a Person parameter
        // because Employee derives from Person.
        Action<Employee> addEmployeeToContacts = AddToContacts;

        // You can also assign a delegate 
        // that accepts a less derived parameter to a delegate 
        // that accepts a more derived parameter.
        addEmployeeToContacts = addPersonToContacts;
    }
}

参照

その他の技術情報

共変性と反変性 (C# および Visual Basic)

.NET Framework におけるジェネリック