zoukankan      html  css  js  c++  java
  • Covariance and Contravariance (C#)

    Covariance and Contravariance (C#)

    https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/concepts/covariance-contravariance/

    In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments.

    Covariance preserves assignment compatibility and contravariance reverses it.

    The following code demonstrates the difference between assignment compatibility, covariance, and contravariance.

            
            // Assignment compatibility.   
            string str = "test";
            // An object of a more derived type is assigned to an object of a less derived type.   
            object obj = str;
    
            // Covariance.   
            IEnumerable<string> strings = new List<string>();
            // An object that is instantiated with a more derived type argument   
            // is assigned to an object instantiated with a less derived type argument.   
            // Assignment compatibility is preserved.   
            IEnumerable<object> objects = strings;
    
            // Contravariance.             
            // Assume that the following method is in the class:   
            // static void SetObject(object o) { }   
            Action<object> actObject = SetObject;
            // An object that is instantiated with a less derived type argument   
            // is assigned to an object instantiated with a more derived type argument.   
            // Assignment compatibility is reversed.   
            Action<string> actString = actObject;

    public delegate void Action<in T>(T obj)   Action的泛型委托,里面的T指定了是逆变的,本来的返回值类型是object的。现在范围缩小成string,不会影响程序的运行。

    Covariance for arrays enables implicit conversion of an array of a more derived type to an array of a less derived type.

    But this operation is not type safe, as shown in the following code example.

    object[] array = new String[10];  
    // The following statement produces a run-time exception.  
    // array[0] = 10;

    Covariance and contravariance support for method groups allows for matching method signatures with delegate types.

    This enables you to assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type.

    For more information, see Variance in Delegates (C#) and Using Variance in Delegates (C#).

    The following code example shows covariance and contravariance support for method groups.

    static object GetObject() { return null; }  
    static void SetObject(object obj) { }  
    
    static string GetString() { return ""; }  
    static void SetString(string str) { }  
    
    static void Test()  
    {  
        // Covariance. A delegate specifies a return type as object,  
        // but you can assign a method that returns a string.  
        Func<object> del = GetString;  
    
        // Contravariance. A delegate specifies a parameter type as string,  
        // but you can assign a method that takes an object.  
        Action<string> del2 = SetObject;  
    }

    In .NET Framework 4 or newer C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters.

    For more information, see Variance in Generic Interfaces (C#) and Variance in Delegates (C#).

    The following code example shows implicit reference conversion for generic interfaces.

    IEnumerable<String> strings = new List<String>();  
    IEnumerable<Object> objects = strings;

    A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant.

    C# enables you to create your own variant interfaces and delegates.

    For more information, see Creating Variant Generic Interfaces (C#) and Variance in Delegates (C#).

    Covariance and Contravariance in Generics

    http://msdn.microsoft.com/en-us/library/dd799517.aspx

    Covariance and contravariance are terms that refer to the ability to use a less derived (less specific) or more derived type (more specific) than originally specified.

    Generic type parameters support covariance and contravariance to provide greater flexibility in assigning and using generic types.

    When you are referring to a type system, covariance, contravariance, and invariance have the following definitions.

    The examples assume a base class named Base and a derived class named Derived.

    • Covariance  协变

      Enables you to use a more derived type than originally specified.

      You can assign an instance of IEnumerable<Derived> (IEnumerable(Of Derived) in Visual Basic) to a variable of type IEnumerable<Base>.

    • Contravariance  逆变

      Enables you to use a more generic (less derived) type than originally specified.

      You can assign an instance of IEnumerable<Base> (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable<Derived>.

    • Invariance  不变性,恒定性

      Means that you can use only the type originally specified; so an invariant generic type parameter is neither covariant nor contravariant.

      You cannot assign an instance of IEnumerable<Base> (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable<Derived>or vice versa.

    Covariant type parameters enable you to make assignments that look much like ordinary Polymorphism, as shown in the following code.

  • 相关阅读:
    写在我第一个虚幻程序之前
    C++学习笔记(十二):重载函数
    JavaScript兼容问题汇总[实时更新]
    Activity跳转时传递Bitmap对象的实现
    Http报头Accept与Content-Type的差别
    第0讲: 准备篇
    Android Design Support Library(二)用NavigationView实现抽屉菜单界面
    Android Design Support Library(一)用TabLayout实现类似网易选项卡动态滑动效果
    Android Support Library 23.2用法简析
    Android Design Support Library初探,NavigationView实践
  • 原文地址:https://www.cnblogs.com/chucklu/p/4221175.html
Copyright © 2011-2022 走看看