接口中的协方差和反演:

时间:2016-11-12 19:43:52

标签: c# covariance contravariance

以下是对泛型使用协方差和逆变的示例

 class Program
    {
        static void Main(string[] args)
        {
            ICovariant<Apple> alCov = new Covariant<Apple>();
            ICovariant<Fruite> fCov = alCov;

            IContravariant<Apple> aContra = new Contravariant<Apple>();
            IContravariant<Apple> fContra = new Contravariant<Fruite>();

        }


        public class Fruite
        {
            public virtual void Print()
            {
                Console.WriteLine("Fruite");
            }
        }

        public class Apple : Fruite
        {
            public override void Print()
            {
                Console.WriteLine("Apple");
            }
        }

        interface IContravariant<in T>
        {
            void Method();

            // This interface can be implicitly cast to MORE DERIVED (downcasting)
            // Usually means T is used as argument
            void Method(T argument);
        }//interface

        interface ICovariant<out T>
        {
            // This interface can be implicitly cast to LESS DERIVED (upcasting)
            // Used for readonly collections
            IEnumerable<T> GetList { get; }
            // Used when T is used as return type
            T Method();
        }//interface


        public class Covariant<T> : ICovariant<T>
        {
            public IEnumerable<T> GetList
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public T Method()
            {
                throw new NotImplementedException();
            }
        }
        public class Contravariant<T> : IContravariant<T>
        {
            public void Method()
            {
                Console.Write(typeof(T));
            }

            public void Method(T argument)
            {
                Console.Write(argument);
            }
        }

    }

我理解这些代码行,因为它类似于多态,我理解它背后的好处

ICovariant<Apple> alCov = new Covariant<Apple>();
ICovariant<Fruite> fCov = alCov;

但我不明白的是逆变的好处,如以下几行

IContravariant<Apple> aContra = new Contravariant<Apple>();
IContravariant<Apple> fContra = new Contravariant<Fruite>();

所以任何人都可以解释一下如何利用它的例子。

1 个答案:

答案 0 :(得分:1)

so could anyone explain with example of how can I take the benefit of it.

使用的一个例子如下:

 IContravariant<Fruite> fContra = new Contravariant<Fruite>();
 List<IContravariant<Apple>>  contravariants=  new List<IContravariant<Apple>>();
 contravariants.Add(fContra);
 contravariants.Add(aContra);

所以如果您更改了IContavariant<in T>界面 到IContavariant<T>您将收到编译时错误

一个很好的例子可能是Distinct中的Linq方法你可以想到一个方法做同样的事情,但不使用IEqualityComparer<T>但是对所有水果使用相同的算法

在此链接中,您可以找到完整的示例 Comparing Generic Collections