Parameter must be input-safe error

前端 未结 1 1134
北恋
北恋 2021-01-14 19:49

Here is a piece of my code:

public interface IA
{
    void Method(IB entities);
}

public interface IB { }
         


        
相关标签:
1条回答
  • 2021-01-14 19:51

    The designator of contravariance in C# (i.e. in) is intuitive only at the immediate level, when you make a method that "takes in" a parameter of generic type. Internally, however, contravariance means an inversion of a relation (Q&A with an explanation) so using in inside IA makes it incompatible with IB.

    The problem is best illustrated with an example. Consider class Animal and its derived class Tiger. Let's also assume that IB<T> has a method void MethodB(T input), which is called from IA's Method:

    class A_Impl<T> : IA<T> {
        T data;
        public void Method(IB<TInput> entities) {
            entities.MethodB(data);
        }
    }
    

    Declaring IA<in TInput> and IB<in TInput> means that you can do

    IA<Animal> aForAnimals = new A_Impl<Animal>();
    IA<Tiger> aForTigers = aForAnimals;
    

    IA<in TInput> has a method that takes IB<TInput>, which we can call like this:

    aForTigers.Method(new B_Impl<Tiger>());
    

    This is a problem, because now A_Impl<Animal> passes an Animal to MethodB of an interface that expects a Tiger.

    You would have no problem with IB<out T>, though - both with covariance and contravariance:

    public interface IB<out T> {
    //                  ^^^
    }
    // This works
    public interface IA<in TInput> {
        void Method(IB<TInput> x);
    }
    // This works too
    public interface IC<out TInput> {
        void Method(IB<TInput> x);
    }
    
    0 讨论(0)
提交回复
热议问题