繁体   English   中英

一般方法不支持强制转换为基类型

[英]cast to base-type not supported for generic method

我有一个接口IGenericOrder如下:

using System;
using System.Linq.Expressions;

namespace MyNamespace
{
    interface IGenericOrder<T> where T : new()
    {
        Func<T, int> GetStatement(string name);
    }


    public class GenericOrder<T> : IGenericOrder<T> where T : new()
    {
        public Func<T, int> GetStatement(string name)
        {
            return (T) => 4;
        }    
    }
}

现在,当我创建该类的实例并将其转换回IGenericOrder<object>

var sorter = (IGenericOrder<object>) new GenericOrder<Foo>();

我得到例外:

InvalidCastException: GenericOrder<Foo>类型的实例无法强制转换为IGenericOrder<object>

这似乎很清楚,因为接口IGenericOrder不是协变的。 但是,如果我使接口协变( interface IGenericOrder<out T> ),我得到一个编译器错误:

方差无效:类型参数“T”必须在IGenericOrder<T>.GetStatement(string)IGenericOrder<T>.GetStatement(string)有效。 'T'是协变的。

正如我从这里读到的那样,协方差只能用于

[泛型类型参数]仅用作方法返回类型,不用作形式方法参数的类型。

这是否意味着我不能对自己返回通用实例的方法使用共同/逆变?

我正在使用.Net 4.5

要了解发生了什么,请查看Func<T,TResult>委托的定义:

public delegate TResult Func<in T, out TResult>(
    T arg
)

如您所见,其第一个类型参数Tin参数。 因此,您不能将out参数用作Func的第一个类型参数。 第二个类型参数TResult已经out ,因此使用T作为TResult可以工作:

interface IGenericOrder<out T> where T : new() {
    Func<int,T> GetStatement(string name);
}

public class GenericOrder<T> : IGenericOrder<T> where T : new() {
    public Func<int,T> GetStatement(string name) {
        return (x) => default(T);
    }    
}

演示。

您使用T作为Func的第一个类型参数,因此唯一有效的模式是变量,因为T表示函数参数的类型。 你试图通过你的演员实现的是不安全的:你说“这是一个以Foo为参数的函数。请把它当作一个以任何object作为参数的函数。” 如果您有一个Func<int, T> ,则可以使用协方差,因为返回Foo的函数也可以被视为返回object的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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