简体   繁体   中英

Covariance with generic type and expression

I am trying to use covariance in my Program, but when I use Expression<Func<T>> in my method as parameter, I get the following error

Parameter must be input-safe. Invalid variance.
The Type parameter T must be invariently valid on Expression <TDelegate>

Is there any way to use expresssion as parameter in method along with covariance ?

Example below

class Program
    {
        static void Main(string[] args)
        {
            var temp = new Temp<People>();
            TestMethod(temp);

        }

        public static void TestMethod(ITemp<Organism> param)
        {

        }
    }

    class Temp<T> : ITemp<T>
        where T : Organism
    {
        public void Print() {}

        public void SecondPrint(Expression<Func<T>> parameter) {}
    }


    class People : Organism {}
    class Animal : Organism {}
    class Organism {}

    interface ITemp<out T> where T : Organism
    {
        void SecondPrint(Expression<Func<T>> parameter);
    }

See this Eric Lippert 's answer :

The "out" means "T is only used in output positions". You are using it in an input position

(even if it is the return type of the Func delegate). If the compiler allowed that, you could write (in your example):

static void Main(string[] args)
{
    var temp = new Temp<People>();
    TestMethod(temp);
}

public static void TestMethod(ITemp<Organism> param)
{
    param.SecondPrint(() => new Animal());
}

Calling SecondPrint on Temp<People> , but passing a lambda that returns an Animal .

I would remove the variance annotation on T :

interface ITemp<T> where T : Organism
{
    void SecondPrint(Expression<Func<T>> parameter);
}

and make TestMethod parametric in T :

public static void TestMethod<T>(ITemp<T> param) where T : Organism
{
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM