使用泛型和表达式的协变性

4
我正在尝试在我的程序中使用协变(covariance),但是当我在我的方法中使用Expression<Func<T>>作为参数时,我会收到以下错误信息:

参数必须是输入安全的。无效的方差。
类型参数T必须在Expression <TDelegate>上不变地有效。

有没有办法在方法中使用表达式(expression)作为参数以及协变(covariance)?

下面是一个示例:

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);
    }
1个回答

0
看看Eric Lippert答案

"out"表示"T仅用于输出位置"。你正在使用它在输入位置

即使它是Func委托的返回类型,如果编译器允许,你可以编写(在你的示例中):
static void Main(string[] args)
{
    var temp = new Temp<People>();
    TestMethod(temp);
}

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

Temp<People> 上调用 SecondPrint,但传递了一个返回 Animal 的 lambda 表达式。

我会移除 T 上的 variance 注释:

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

并使TestMethod成为T的参数:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接