Covariance and contravariance real world example

后端 未结 9 2020
醉梦人生
醉梦人生 2020-11-22 16:57

I\'m having a little trouble understanding how I would use covariance and contravariance in the real world.

So far, the only examples I\'ve seen have been the same o

9条回答
  •  时光说笑
    2020-11-22 17:49

    The in and out keywords control the compiler's casting rules for interfaces and delegates with generic parameters:

    interface IInvariant {
        // This interface can not be implicitly cast AT ALL
        // Used for non-readonly collections
        IList GetList { get; }
        // Used when T is used as both argument *and* return type
        T Method(T argument);
    }//interface
    
    interface ICovariant {
        // This interface can be implicitly cast to LESS DERIVED (upcasting)
        // Used for readonly collections
        IEnumerable GetList { get; }
        // Used when T is used as return type
        T Method();
    }//interface
    
    interface IContravariant {
        // This interface can be implicitly cast to MORE DERIVED (downcasting)
        // Usually means T is used as argument
        void Method(T argument);
    }//interface
    
    class Casting {
    
        IInvariant invariantAnimal;
        ICovariant covariantAnimal;
        IContravariant contravariantAnimal;
    
        IInvariant invariantFish;
        ICovariant covariantFish;
        IContravariant contravariantFish;
    
        public void Go() {
    
            // NOT ALLOWED invariants do *not* allow implicit casting:
            invariantAnimal = invariantFish; 
            invariantFish = invariantAnimal; // NOT ALLOWED
    
            // ALLOWED covariants *allow* implicit upcasting:
            covariantAnimal = covariantFish; 
            // NOT ALLOWED covariants do *not* allow implicit downcasting:
            covariantFish = covariantAnimal; 
    
            // NOT ALLOWED contravariants do *not* allow implicit upcasting:
            contravariantAnimal = contravariantFish; 
            // ALLOWED contravariants *allow* implicit downcasting
            contravariantFish = contravariantAnimal; 
    
        }//method
    
    }//class
    
    // .NET Framework Examples:
    public interface IList : ICollection, IEnumerable, IEnumerable { }
    public interface IEnumerable : IEnumerable { }
    
    
    class Delegates {
    
        // When T is used as both "in" (argument) and "out" (return value)
        delegate T Invariant(T argument);
    
        // When T is used as "out" (return value) only
        delegate T Covariant();
    
        // When T is used as "in" (argument) only
        delegate void Contravariant(T argument);
    
        // Confusing
        delegate T CovariantBoth(T argument);
    
        // Confusing
        delegate T ContravariantBoth(T argument);
    
        // From .NET Framework:
        public delegate void Action(T obj);
        public delegate TResult Func(T arg);
    
    }//class
    

提交回复
热议问题